[More quick guides]

A quick guide to
creating sidenotes
in Prince 15

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 the latest version of Prince 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 considered 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="../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, all notes have markers, but only the footnotes have calls in the main text. Sidenote calls are added 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="../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 }

Spreaded tracks

..

htmlxx

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.

Sidenote captions

When figures are floated to the top and bottom of a page, their respective captions can be floated in the sidenote area:

htmlfigure.top { -prince-float: top; -prince-clear: end }
figure.top figcaption { -prince-float: sidenote top }

figure.bottom { -prince-float: bottom; -prince-clear: end }
figure.bottom figcaption { -prince-float: sidenote bottom }

The use of 'clear' is essential in the above example; if there is more than once caption at the top/bottom, the caption will not be correctly aligned.

Sidenote captions, aligning with non-floating figures

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. 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.

Sidenote captions, aligning with bottom edge of top-floating figures

When figures are floated to the top of a page, the corresponding caption can be nicely aligned in the sidenote area:

htmlfigure.top { -prince-float: top; -prince-clear: end }
figure.top figcaption { -prince-float: sidenote align-bottom }

The align-bottom keyword means that the bottom of the sidenote will be aligned with the top of the box where it naturally appears. In the example above, the box where the figcaption naturally appears is not the figure (which has been floated away to the top), but the box which contains the main text flow. (This is not so intuitive. It might be better to find a way to align with the figure element.)

Sidenote captions, aligning with top edge of bottom-floating figures

Aligning the caption with the top edge of a bottom-floating figure is a bit tricky to achieve (due to both align-top/align-bottom being aligned with the top of a box). It involves making the figure box wide, and thereafter size and place the image and caption within the wide box:

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

figure.bottom { 
  -prince-float: bottom wide; -prince-clear: end }

figure img { 
  width: 65%; 
  -prince-float: inside;
}
figure figcaption { 
  width: 35%; 
  -prince-float: outside; 
  box-sizing: border-box; /* this has to be present, for reasons I do not understand */
}

Icons

Sidenotes are useful for many kinds or marginal notes, including icons

html@page {
  @leftnote { width: 5vw }
}

p.note::before {
  -prince-float: sidenote;
  content: "📝";
  font-family: "Noto Emoji";
  width: 3vw;
}

2024-04-22 Håkon Wium Lie