CSS Pagination

In CSS, pagination refers to the styling and layout of content that spans multiple pages. While many developers think of "pagination" as the row of numbers at the bottom of a search result, CSS pagination specifically deals with how content is divided and displayed when printed or saved as a PDF. This includes controlling where pages start, setting physical dimensions, and handling page numbering automatically.

Developer Tip: Use the @media print query in your CSS to wrap these styles. This ensures your pagination rules only apply when printing or exporting to PDF, and won't affect the layout of your live website.

1. Page Breaks

page-break-before and page-break-after

These properties are the manual "switches" that tell the browser exactly where a new page should begin. This is crucial for reports where you want every new chapter or major section to start at the top of a fresh sheet of paper.

  • page-break-before: Forces a page break to occur before the element. Often used on <h1> tags in long documents.
  • page-break-after: Forces a page break after an element is rendered.
/* Standard usage for document sections */
h2.chapter-title {
    page-break-before: always;
}

.report-summary {
    page-break-after: always; /* Ensure the next section starts fresh */
}
Watch Out: The page-break-* properties are being replaced by the more modern break-before and break-after properties. While page-break still has excellent support, consider using break-before: page; for forward compatibility.
Common Mistake: Applying page breaks to <span> or other inline elements. Page breaks only work reliably on block-level elements like <div>, <section>, or <h1-h6>.

2. Page Size and Margins

size and margin

The @page at-rule is a unique CSS tool that targets the physical page itself rather than the HTML elements. This allows you to define the geometry of the printed document.

  • size: Defines the target paper size. You can use standard keywords like A4, letter, or landscape, or provide exact dimensions (e.g., size: 8.5in 11in;).
  • margin: Sets the white space around the edges of the page. This is vital for ensuring text doesn't get "cut off" by the printer's physical margins.
@page {
    size: A4; /* Sets the paper size to international A4 */
    margin: 1in; /* Provides a 1-inch safe zone on all sides */
}

/* You can even target the first page specifically */
@page :first {
    margin-top: 2in; /* Larger top margin for a title page */
}
Best Practice: Always include a generous margin (at least 1cm or 0.5in) in your @page rule. Different printers have different "printable areas," and tight margins may result in your content being cropped.

3. Page Numbering

counter-reset and content

CSS provides a built-in counter system that can automatically track and display page numbers. This avoids the need for manual numbering in your HTML, which would become impossible as content grows or shrinks.

  • counter-reset: Initializes a counter (usually set to 0). This is typically placed in the @page rule or on the body.
  • counter-increment: Used to increase the value of the counter every time a specific element is encountered.
  • content: Used within a pseudo-element (like ::after) to display the current value of the counter.
/* Initialize the counter on the body */
body {
    counter-reset: pageCounter;
}

/* Increment the counter for every element with the class 'page-item' */
.page-item {
    counter-increment: pageCounter;
}

/* Display the current number */
.page-item::after {
    content: "Page " counter(pageCounter);
    font-size: 10pt;
    color: #666;
}
Developer Tip: While some modern PDF generators support content: counter(page) inside @page margin boxes, standard browser support for printing page numbers directly from CSS is still evolving. For the most consistent results across all browsers, it's often best to increment counters on block-level elements.

Example

In this practical example, we create a multi-page report structure. Every <section> with the class .chapter will start on a new page, and a footer will display the page number automatically.

/* Print Specific Styles */
@media print {
    @page {
        size: letter;
        margin: 2cm;
    }

    body {
        counter-reset: sectionCount;
        font-family: serif; /* Better for reading printed text */
    }

    .chapter {
        page-break-before: always;
        counter-increment: sectionCount;
        padding-bottom: 20px;
    }

    .chapter::after {
        content: "Section " counter(sectionCount);
        display: block;
        text-align: center;
        font-style: italic;
        margin-top: 30px;
        border-top: 1px solid #ccc;
    }
}

/* HTML Structure */
<div class="report">
    <div class="chapter">
        <h1>Executive Summary</h1>
        <p>This document outlines the quarterly results...</p>
    </div>
    
    <div class="chapter">
        <h1>Market Analysis</h1>
        <p>Trends show a significant increase in...</p>
    </div>
    
    <div class="chapter">
        <h1>Financial Projections</h1>
        <p>Our outlook for the next fiscal year is...</p>
    </div>
</div>

In this example:

  • The @page rule ensures the document uses standard letter size with appropriate margins.
  • Each .chapter triggers a page break, ensuring your sections don't run into each other.
  • We use counter-increment on the chapter itself to keep track of the section numbers automatically.

Notes and Considerations

  • Browser Support: Basic properties like page-break-before are universally supported. However, advanced features like @page margin boxes (e.g., @top-left) have limited support in standard browsers and are mostly used with specialized PDF tools like PrinceXML or WeasyPrint.
  • Print Media: Always test your pagination by using the "Print Preview" feature in your browser. What looks good on a wide 1080p monitor may look very different on an 8.5" wide piece of paper.
  • Responsive Design: Avoid using fixed pixel (px) widths for printed content. Instead, use relative units like % or physical units like in or cm to ensure the content fits the paper size correctly.
Best Practice: Use break-inside: avoid; on elements like images, tables, or small "info boxes" to prevent them from being split awkwardly across two different pages.

By mastering CSS pagination, you can bridge the gap between web content and professional document design, ensuring your users get a polished experience whether they are reading on a screen or a physical printout.