Current status
Native header/footer support via @page margin boxes is on the roadmap.
Today there are two practical approaches: (a) CSS fixed positioning for
simple headers and footers that repeat on every page, and (b) HTML structure
with repeating table headers for column-heavy documents.
CSS fixed positioning (works today)
Use position: fixed to place content at a fixed position on every rendered page.
Add matching body margins so the main content does not overlap the header or footer areas:
<style>
.page-header {
position: fixed;
top: 0; left: 0; right: 0;
height: 40px;
font-size: 10px;
color: #666;
border-bottom: 1px solid #e5e7eb;
display: flex;
align-items: center;
padding: 0 20px;
}
.page-footer {
position: fixed;
bottom: 0; left: 0; right: 0;
height: 30px;
font-size: 9px;
color: #999;
border-top: 1px solid #e5e7eb;
text-align: center;
line-height: 30px;
}
body {
margin-top: 50px; /* leave room for header */
margin-bottom: 40px; /* leave room for footer */
}
</style>
<div class="page-header">My Company — Confidential</div>
<div class="page-footer">Document Title · Page 1</div>
Note: Page number variables such as counter(page) are not yet supported with fixed
positioning. Static text works well; dynamic page numbers require the planned
@page margin box support.
Repeating table headers (works today)
For table-heavy documents, <thead> automatically repeats at the top of each page.
This doubles as a column header on every page and requires no extra CSS:
<table>
<thead>
<tr>
<th>Invoice #</th>
<th>Date</th>
<th>Amount</th>
</tr>
</thead>
<tbody>
<!-- rows repeat across pages, thead repeats too -->
</tbody>
</table>@page margin boxes (planned)
When margin box support ships, headers and footers will use standard CSS @page
margin box syntax — the same as Chrome's print stylesheet support:
@page {
margin: 2cm 2cm 3cm 2cm; /* extra bottom space for footer */
@top-center {
content: "My Document";
font-size: 9pt;
color: #666;
}
@bottom-center {
content: "Page " counter(page) " of " counter(pages);
font-size: 8pt;
}
}
@page :first {
@top-center { content: none; } /* no header on first page */
}This is not yet implemented. Track progress on GitHub.