[More quick guides]

A quick guide to
creating sidenotes
in Prince

Come, side with me

Books often use sidenotes to hold notes and figures in the margin, next to the main flow. Prince now supports such sidenotes through simple extensions to the float property, and we invite you to download and try formatting the code snippets in this guide. Prince is a HTML-to-PDF-via-CSS converter which offers advanced layout features so that you can create books from HTML.

To get started, we define a sidenote area inside @page section of the CSS stylesheet. In this example, we create a sidenote area on the right side of the flow:

html@page {
  @rightnote { width: 40vw }
}
aside {
  -prince-float: sidenote;
  background: beige;
}

<aside>Did you hear about...
<aside><img ...
<aside>Why don't scientists...
<aside><img ...

In the above example, aside elements are moved to the sidenote area (defined with @rightnote) which is given a 40vw width. You cannot set the height of the sidenote area (it always has the height of the main flow), but you can set other box-relasted properties, like padding and background.

Left and right

There can be two sidenote areas on a page, one on the left and one on the right. Here they are given a width, and some padding to separate them from the main flow:

html@page {
  @leftnote {
    width: 30vw;
    padding-right: 1em;
  }
  @rightnote {
    width: 30vw;
    padding-left: 1em;
  }
}
aside { -prince-float: rightnote }
figure { -prince-float: leftnote }

The sidenote area is referred to as rightnote and leftnote when you need to distinguish between them, otherwise the generic sidenote will do.

Stacked

By default, sidenotes appear near their anchoring points. But they can also be floated to the top or bottom of the sidenote area:

html@page {
  @leftnote {
    width: 30vw;
  }
  @rightnote {
    width: 30vw;
  }
}

aside { -prince-float: rightnote top }
figure { -prince-float: leftnote bottom }

Sidenotes on multi-column pages

Sidenotes work well in multi-column environments where negative margins (which can be used to emulate sidenotes) will fail.

htmlbody { columns: 2 }
.joke { 
  -prince-float: sidenote; 
  font-style: italic;
}

Numbering sidenotes

Unlike footnotes, sidenotes are not automatically numbered. This is something that might be considererd for the fugure. Meanwhile, a small script can help us:

htmlbody { columns: 2 }
.joke { 
  -prince-float: sidenote; 
  font-style: italic;
}
.joke::before {
   content: "[" counter(sn) "] ";
}

.snc {
   counter-increment: sn;
   content: "[" counter(sn) "] ";
}

<script type="text/javascript" src="https://css4.pub/2022/charms.js"></script>
<body onload="addSidenoteMarks('span','snc')">

The script will look for span elements, and create corresponding sidenote call elements, of class snc.

Sidenotes and footnotes

The sidenote areas are conceptually similar to the footnote area, and all of them can be used on the same page:

html@page {
  @leftnote { 
    width: 30vw;
    padding-right: 1em;
  }
  @rightnote { 
    width: 30vw;
    padding-left: 1em;
  }
  @footnote {
    border-top: solid black thin;
    padding-top: 8pt;
  }
}

.fn { -prince-float: footnote }
::footnote-marker { content: "[" counter(footnote) "] " }
.greek { -prince-float: leftnote }
.greek::before { content: "[" counter(cg, lower-greek) "] " }
.roman { -prince-float: rightnote }
.roman::before { content: "[" counter(cr, lower-roman) "] " }

Complex numbering of sidenotes

In the previous example, only the true footnotes have calls in the main text. This is fixed with a small script:

html@page {
  @leftnote { 
    width: 30vw;
    padding-right: 1em;
  }
  @rightnote { 
    width: 30vw;
    padding-left: 1em;
  }
  @footnote {
    border-top: solid black thin;
    padding-top: 8pt;
  }
}

body {
  counter-reset: cr cg;
}

.fn { -prince-float: footnote }
::footnote-marker { content: "[" counter(footnote) "] " }
.greek { -prince-float: leftnote }
.greek::before { content: "[" counter(cg, lower-greek) "] " }
.roman { -prince-float: rightnote }
.roman::before { content: "[" counter(cr, lower-roman) "] " }

.croman {
   counter-increment: cr;
   content: "[" counter(cr, lower-roman) "] ";
}

.cgreek {
   counter-increment: cg;
   content: "[" counter(cg, lower-greek) "] ";
}

<script type="text/javascript" src="https://css4.pub/2022/charms.js"></script>
<body onload="addSidenoteMarks('.roman','croman'); addSidenoteMarks('.greek','cgreek')">

Shorthand and individual properties

The float property is a shorthand; the underlying individual properties can also be used:

html@page {
  @leftnote {
    width: 30vw;
  }
  @rightnote {
    width: 30vw;
  }
}

aside { 
  -prince-float-reference: rightnote;
  -prince-float-placement: top;
}
figure { 
  -prince-float-reference: leftnote;
  -prince-float-placement: bottom;
}

Spreads

The sidenote areas can have different widths and background colors on different pages. Also notes can be floated to the outside and inside sidenote areas:

html@page :left {
  @leftnote {
    width: 20vw;
    background: peachpuff;
  }
  @rightnote {
    width: 40vw;
    background: palegreen;
  }
}

@page :right {
  @leftnote {
    width: 25vw;
    background: honeydew;
  }
  @rightnote {
    width: 35vw;
    background: linen;
  }
}

@page:nth(3) {
  @leftnote {
    width: 40vw;
    background: khaki;
  }
  @rightnote {
    width: 10vw;
    background: lightcyan;
  }
}

.ref { -prince-float: top outsidenote }
aside { -prince-float: insidenote }

Wide, wide-left and wide-right

Often, a wide figure will extend into the margin area. This can be expressed with the wide, wide-left and wide-right keywords. In this example, the first three figures extend into both sidenote areas, while the last figure remains in the main flow.

html@page {
  @leftnote {
    width: 30vw;
  }
  @rightnote {
    width: 30vw;
  }
}
.w { -prince-float: wide }
.wl { -prince-float: wide-left }
.wr { -prince-float: wide-right }
...
<figure class=w><img src=sinus.svg></figure>
...
<figure class=wl><img src=sinus.svg></figure>
...
<figure class=wr><img src=sinus.svg></figure>
...
<figure><img src=sinus.svg></figure>
...

Wide-inside and wide-outside

There are also wide-inside and wide-outside keywords:

html@page {
  @leftnote {
    width: 30vw;
  }
  @rightnote {
    width: 30vw;
  }
}
figure.sinus { 
  -prince-float: wide-inside;
}
figure.tangent { 
  -prince-float: wide-outside;
}

Wide figues with captions

Wide figures can also be combined with captions in the sidenote area:

html@page {
  @rightnote { width: 40vw }
}

figure {
  -prince-float-reference: wide;
}

figure figcaption {
  -prince-float-placement: inherit;
  -prince-float-reference: sidenote;
  background: beige;
}

.top { -prince-float-placement: top }
.bottom { -prince-float-placement: bottom }

Notice how the figure caption is placed below the top figure and above the bottom figure. This due to wide figures being laid out before other sidenotes.

Captions in the sidenote area

Captions placed in the sidenote area must be connected with their figure. The order of the figcaption and img elements is relevant to achieve these common placements:

htmlfigcaption.align-top {
  -prince-float: sidenote align-top;
}

figcaption.align-bottom {
  -prince-float: sidenote align-bottom;
}

<figure>
  <figcaption class=align-top>A sine ...
  <img src=tangent.svg>
</figure>

<figure>
  <img src=tangent.svg>
  <figcaption class=align-bottom>A sine ...
</figure>

The align-top keyword means that the top of the sidenote will be aligned with the top of the box where it naturally appears. So float: sidenote align-top in plain English is saying:

However, if more than one sidenote naturally appears on the same line, the sidenotes will be stacked in the content order, so all requests cannot be grated.

There is a corresponding align-bottom keyword where the bottom of the sidenote is aligned with the top of the box where it naturally appears.

Captions in the sidenote area, attached to top- or bottom-floating figures

Aligning captions like you see in the image below requires a hack: the caption must be absolutely positioned within a wide figure element, and the width of the image and caption must be set manually.

html@page {
  @rightnote { width: 40vw }
}

figure { position: relative; }
figure img { width: 65% }
figure figcaption { 
  width: 35%; position: absolute; right: 0; 
  background: beige; box-sizing: border-box;
}

figure.top { -prince-float: top wide }
figure.top figcaption { bottom: 0 }

figure.bottom { -prince-float: bottom wide }
figure.bottom figcaption { top: 0 }

Captions in the sidenote area, attached to top- or bottom-floating figures on spreads

To achieve the alignment from the previous example on pages with different left/right sidenote areas, a small script is needed for top-floating figures.

html@page:left {
  @leftnote { width: 40vw }
}
@page:right {
  @rightnote { width: 40vw }
}

figure.bottom { -prince-float: bottom wide }
figure.bottom img { width: 65%; float: inside }
figure.bottom figcaption { width: 35%; float: outside }

figure.top { -prince-float: top wide }
figure.top img { display: inline-block; width: 60%; float: inside }
figure.top figcaption { display: inline-block; width: 30%; float: outside }

<script type="text/javascript" src="https://css4.pub/2022/charms.js"></script>
<body onload="alignCaptions('figure.top figcaption')">

2022-04-05 HÃ¥kon Wium Lie