PrintCSS: Running Headers and Footers

Andreas Zettl
PrintCSS
Published in
4 min readOct 10, 2020

If you want to use HTML inside the page margin boxes, you will need to use running elements. These elements are normal HTML nodes with the CSS position property set to ‘running(NAME)’.

The name given to the running element is used within the page margin boxes to set their content to the running elements inner HTML.

To do so, you need to set the specific page margin box’s CSS content property to ‘element(NAME)’, where NAME is the given running element name.

Elements with the position running do not appear in the document until you assign them to some CSS content property.

Your running elements must come first in your HTML structure. For example, if you put the footer element before the closing body tag, the running footer will only appear on the last page.

Sample Header

So after reading the theory, let’s jump right in and create a small example. We will define a running header with a simple text and a footer with HTML content.

In the body of our document, let’s define our two header div elements.

<div class="headerLeft">
Running Headers and Footers
</div>
<div class="headerRight">
A sample document
</div>

As mentioned above, we now need to define the position as ‘running’, and we will also give our headers some basic style.

.headerLeft{
position: running(headerLeft);
font-size:12pt;
}
.headerRight{
position: running(headerRight);
font-size:8pt;
font-style: italic;
text-align: right;
color:#667eea;
}

Before we render the PDF, we need to define the page margin boxes and the page in CSS.

@page  {
size: A6;
margin: 20mm;
@top-left{
content: element(headerLeft);
border-bottom:2px solid #434190;
}
@top-center{
border-bottom:2px solid #434190;
}
@top-right{
content: element(headerRight);
border-bottom:2px solid #434190;
}
}

As you can see, the page size is A6, and we have a margin of 2cm for all sides of the page. Our running header elements are used in the ‘@top-left’ and ‘@top-right’ definition. Additionally, I added a bottom border to all top margin boxes.

The rendering result always depends on the tool you are using. Here are two samples with PDFreactor and Prince.

Prince rendering result of running headers
Result with Prince
Rendering result of the running header with the tool PDFreactor
PDFreactor Result

More tools you can check on printcss.live.

Sample Footer

Now, as we have the header ready, let’s have a look at the footer. I want to put a logo on the left side and contact information on the right in the footer. Between both, I want to add the current and total page numbers.

<div class="footerLeft">
<img src="https://printcss.live/img/logo.png" />
</div>
<div class="footerRight">
<a href="mailto:info@azettl.net">info@azettl.net</a>
<br />
<a href="https://printcss.live/">printcss.live</a>
</div>

In the CSS, we will give the footer classes a position ‘running’ again and some basic style like the logo’s width.

.footerLeft{
position: running(footerLeft);
}
.footerLeft img{
width:20mm;
}
.footerRight{
position: running(footerRight);
text-align: right;
font-size:8pt;
}

If we render now, we will not see the elements as we still need to assign them to one of the page margin boxes.

Footer rendering result, without assigning the running elements, with the tool Prince.
Result with Prince

We need to define our bottom margin boxes inside the ‘@page’ rule to make this work.

@bottom-right{
content: element(footerRight);
border-top:2px solid #434190;
}
@bottom-center{
content: counter(page) ' / ' counter(pages);
border-top:2px solid #434190;
font-size:8pt;
}
@bottom-left{
content: element(footerLeft);
border-top:2px solid #434190;
}

Again I added some border, this time on the top. Also, you can see in the bottom center margin box I define the content as “counter(page) ‘ / ‘ counter(pages)”. The counter ‘page’ returns us the current page number, while the ‘pages’ counter gives us the total number of pages.

Now our document has a nice header and footer.

Running header and footer rendered with PDFreactor
Running header and footer rendered with PDFreactor

Complete Sample

To see whether our running header and footer elements actually work, we need to add some content. If our code works fine we will see the header and footer on all pages.

The content should be placed inside the body element but after all running header and footer elements.

<div class="content">
<h1>PrintCSS: Running Headers and Footers</h1>
<p>
If you want to use HTML inside the page margin boxes, you will need to use running elements. These elements are normal HTML nodes with the CSS position property set to 'running(NAME)'.
</p>
<p>
The name given to the running element is used within the page margin boxes to set their content to the running elements inner HTML.
</p>
<p>
To do so, you need to set the specific page margin box's CSS content property to 'element(NAME)', where NAME is the given running element name.
</p>
<p>
Elements with the position running do not appear in the document until you assign them to some CSS content property.
</p>
<p>
Your running elements must come first in your HTML structure. For example, if you put the footer element before the closing body tag, the running footer will only appear on the last page.
</p>
</div>

If you render on printcss.live now, you will see the running elements on all pages.

Rendering result with PDFreactor.
Rendering result with PDFreactor.

Complete Code to copy

--

--