I'm developing a feature to generate a PDF health report from an EJS template. I'm trying to add page numbers (e.g., "Page 1 of 10") to the footer of each page. I'm using the CSS Paged Media Module features, specifically counter(page) and the @page rule. While the PDF generates correctly with all the content and page breaks, the page numbers are completely missing.
Problem Description
The goal is to have a "Page X of Y" counter at the bottom of every page in the final PDF file. I have implemented this using CSS counters and the @page at-rule with a @bottom-center margin box. The rest of the report's content and styling, including dynamic page breaks between sections, works as expected. However, the footer with the page number does not appear on any page.
As you can see CSS is being applied but some how I'm not able to see the content text
What I've Tried
My setup involves a Node.js backend that renders an EJS file into HTML, which is then converted into a PDF. Here is the relevant CSS I've added to the section of my report.ejs file. I've intentionally used a large, red font to make sure the page numbers would be noticeable if they were rendering.
.report-container {
/* Initialize the page counter */
counter-reset: page;
}
.section-content {
/* Increment the page counter on each new section that causes a page break */
counter-increment: page;
}
/* Define styles for printing and PDF generation */
@page {
@bottom-center {
/* These properties are my attempt to style the page number */
display: block;
width: 100%;
height: 100%;
position: absolute;
text-align: center;
color: rgb(188, 0, 0); /* Bright red for visibility */
font-size: 45px; /* Very large font size for visibility */
content: "Page " counter(page) " of " counter(pages);
z-index: 1000;
}
}
And this is a simplified version of my EJS/HTML structure that generates the pages. Each page-group is designed to start on a new page (except the first one).
<div class="report-container">
<% pageGroups.forEach((group, index) => { %>
<table class="page-table" <%- index > 0 ? 'style="page-break-before: always;"' : '' %>>
<thead>
<tr>
<td class="page-header">
<!-- Header content -->
</td>
</tr>
</thead>
<tbody>
<tr>
<td class="page-content">
<div class="section-content content-area">
<!-- Main content for the page -->
</div>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td class="page-footer">
<!-- This is empty because I'm trying to use the @page rule for the footer -->
</td>
</tr>
</tfoot>
</table>
<% }); %>
</div>
My Questions
Is there an issue with my CSS or the way I'm incrementing counters that would cause the page numbers not to render? I've read that some CSS properties like position and z-index don't apply to page-margin boxes like @bottom-center. Could including them be breaking the rendering of the content property? Could this be a limitation of the PDF generation library I am using in my Node.js environment? Are there known compatibility issues with counter(pages) or the @page rule in common libraries (like Puppeteer, html-pdf, etc.)?
Expected Outcome
I expect to see a page number, such as "Page 1 of 10", rendered in large red text at the bottom-center of each page of the output PDF. Currently, there is nothing there. Any help or insight into why my page numbers are not visible would be greatly appreciated!
Page <span class="pageNumber"></span> of <span class="totalPages"></span>in thefooterTemplateoption.