PDFPipe

The page box / counter(page)

How to add page numbers to a PDF with CSS

counter(page) and counter(pages) are automatic counters holding the current page number and the total, intended to be used in generated content.

What it is for

They are the mechanism behind page numbering in the paged media specification, and they are the reason people expect page numbers to be a CSS problem.

Support: Does nothing in a browser-based render

These counters only have values inside a page margin box, and browser engines do not implement margin boxes, so the counters have nowhere to be used. Putting counter(page) into a ::before in the document body produces nothing, because the body has no page context.

What to write instead

The specification syntax is shown first so it is recognisable, followed by the approach that produces the result you were after.

css
/* Does nothing: the counter has no value outside a margin box. */
.footer::after { content: counter(page); }

/* Works: the footer template's own substitution classes. */
<div style="font-size:9pt;text-align:right;padding:0 16mm">
  Page <span class="pageNumber"></span> of <span class="totalPages"></span>
</div>

The mistake people make

Every page showing the same number, usually 1. That is the signature of a counter placed in the document body rather than in the footer, where it is evaluated once for the whole document instead of once per page.

Frequently asked

Does counter(page) work when generating a PDF?

Does nothing in a browser-based render. These counters only have values inside a page margin box, and browser engines do not implement margin boxes, so the counters have nowhere to be used. Putting counter(page) into a ::before in the document body produces nothing, because the body has no page context.

How would I know if it were not working?

You would not, from the CSS. Unimplemented and unmatched CSS both fail silently, which is why the reliable test is to set a deliberately extreme value and see whether anything changes. If a 40mm margin looks the same as an 18mm one, the rule is not reaching the page.

Related properties

Things that come up in the same part of a document stylesheet.

Paste the CSS and see what the rendered page does with it.