[More quick guides]

A quick guide to
running headers and footers
in Prince

Born to running

Running headers and footers are found in most books. They are there to remind readers of what they are reading, and to navigate within the book. This guide will show you how to create running headers and footers from your HTML documents.

The formatter of choice is Prince, an HTML-and-CSS-to-PDF converter. The screenshots you see, and the PDF documents linked from this guide, have all been generated with Prince. You can easily create the same pdf files by downloading Prince and pointing it to the HTML links provided in this document.

A basic running header

In the most basic example, a string is placed at the top right of every page in the document:

html@page { @top-right { content: "Chapter 1: The Machine" }}

Inserting a string into the style sheet is easy, but the style sheet is then tied to a specific document. A more reusable style sheet will pick up the string from the document itself.

Using named strings

In the following example, the content of the h2 element is copied into a named string called title. The named string is then, in the second line, referred to inside the string() function:

htmlh2 { string-set: title contents } 
@page { @top-right { content: string(title) }}

When more chapters are added, the running page header is automatically updated:

htmlh2 { 
  string-set: title contents 
  break-before: page;
} 
@page { @top-right { content: string(title) }}

Page numbers

Page numbers are often placed at the bottom of the page:

html@page { @bottom-right { content: counter(page) }}

The predefinded counter called page is automatically increased at every page turn. Another counter, called pages holds the total number of pages in the document.

html@page { @bottom-center { content: counter(page) " of " counter(pages) }}

In the previous example, notice how the two counters are combined with a litera string between them.

Counting chapters

In the examples above, the chapter number has been written into the HTML code. It's often better to use CSS counters to generate these:

html@page { 
  @top-right { 
    content: "Chapter " counter(chapter) ": " string(title);
  }
}
h2 {  
  counter-increment: chapter;
  string-set: title contents;
  break-before: page;
}
h2::before { 
  content: "Chapter " counter(chapter) ": ";
}

Avoiding headers

On the first page of a chapter, where the chapter title is shown, you probably do not want to show a running header.

htmlh2 { 
  string-set: title contents;
  prince-page-group: start;   /* enables :first, see below  */
  break-before: page;
} 
@page { @top-right { content: string(title) }}
@page :first { @top-right { content: none }}

In the above example, the first @page-rule sets a running header on the top right of every page. However, the last @page-rule overrides the first on pages that are considered to be first. Normally, only the first page of a document is considered to be the first. However, by setting prince-page-group on the chapter heading, pages with chapter headings are also considered to be first.

Styling running headers

You can use the CSS properties you know & love on running headers:

html@page { 
  @top-right { 
    content: string(title);
    font-style: italic;
    vertical-align: top;
    padding-top: 1em;
  }
}

Running elements

You can also copy elements into the running headers, not just strings. Here is an example where a mathematical equation is added to the running header:

html@page{
  @top-right {
    content: element(header);
  }
}

div.math {
  position: running(header);
  text-align: right;
}

...

<div class=math>
The solution is:
  <math><msqrt><mi>x</mi></msqrt></math>
</div>

Notice that the text-align property is set on the h3 element; when using running elements, properties are typically set on the element itself, and not inside @page.

A logo on every page

Adding a logo or watermark on every page is easy with running elements:

html@page{
    @bottom-right-corner {
        content: element(logo);
    }
}

img#logo {
  width: 10vw;
  position: running(logo);
}

Running elements in CSS

Pseudo-elements can also be made to run. This way you avoid using HTML elements:

html@page{
  @bottom-left-corner {
    content: element(logo);
  }
}

body:before  {
  width: 10vw;
  content: url(princelogo.png);
  position: running(logo);
}

2022-07-21 HÃ¥kon Wium Lie