Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

CSS paged media turns a continuous HTML document into discrete page boxes for paper or PDF. Use @media print for print-specific presentation (such as hiding navigation), and @page for page dimensions, margins and page-level rules. Then control breaks, render in the exact browser or PDF engine you will ship, and inspect the resulting pages. Standards describe the model, but browser support remains feature- and version-dependent.

The CSS page model

In paged media, content is split across discrete pages. Each page has a page box, a page area where content is laid out, and a surrounding margin area. CSS paged-media specifications also define page selectors, breaks and widow/orphan controls. The CSS Paged Media Level 3 specification is a Working Draft dated 14 September 2023, so it describes an evolving standard rather than a promise that every renderer implements every feature.

Think of the model in layers:

  • Document content: your HTML elements and normal layout.
  • Print presentation: rules inside @media print.
  • Page geometry: @page size, margins and page selectors.
  • Pagination: break properties, widows/orphans and the renderer’s own algorithms.

@media print versus @page

Use @media print for document presentation

This media query applies when a user prints or saves to PDF. It is the right place to remove interactive controls, alter colors, simplify navigation and adjust ordinary elements.

@media print {
  nav,
  .screen-only,
  .chat-widget,
  button {
    display: none !important;
  }

  body {
    color: #000;
    background: #fff;
    font: 10.5pt/1.45 Georgia, serif;
  }

  a {
    color: inherit;
    text-decoration: none;
  }
}

Use @page for page-level layout

@page sets the paper or PDF page size and its margins. It does not select arbitrary HTML descendants or replace normal layout rules.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Sale
HTML and CSS: Design and Build Websites
  • HTML CSS Design and Build Web Sites
  • Comes with secure packaging
  • It can be a gift option
@page {
  size: A4 portrait;
  margin: 20mm;
}

@page :first {
  margin-top: 28mm;
}

@page :left {
  margin-left: 22mm;
  margin-right: 18mm;
}

@page :right {
  margin-left: 18mm;
  margin-right: 22mm;
}

Use physical units deliberately, but verify the result: browser print dialogs can apply scaling, selectable paper sizes and margin settings that alter the final output.

A practical print stylesheet

Start with a screen document that has semantic headings, lists and tables. Add a print stylesheet that defines page geometry, removes screen-only UI and protects important blocks.

@page {
  size: A4;
  margin: 18mm 18mm 22mm;
}

@media print {
  * {
    box-shadow: none !important;
    text-shadow: none !important;
  }

  nav, aside, .screen-only, video, form {
    display: none !important;
  }

  h1, h2, h3 {
    break-after: avoid;
  }

  h1, h2, h3, figure, table, pre {
    break-inside: avoid;
  }

  .chapter {
    break-before: page;
  }

  p, li {
    orphans: 3;
    widows: 3;
  }

  img {
    max-width: 100%;
    height: auto;
  }

  a[href^="http"]::after {
    content: " (" attr(href) ")";
    overflow-wrap: anywhere;
  }
}

Legacy aliases such as page-break-before still appear in older stylesheets, but the modern break-before, break-after and break-inside properties express the intent more clearly. If an older target requires an alias, include both and test the output.

How to control page breaks when printing a webpage

  1. Mark logical starts. Add a class such as chapter to sections that should begin on a fresh page.
  2. Prevent damaging splits. Apply break-inside: avoid to figures, callouts, code samples and short tables. It is a request; if an element is taller than a page, it must split or overflow.
  3. Keep headings with content. Use break-after: avoid on headings and consider a small top margin on the following block.
  4. Control table behavior. Use repeating table headers where the target engine supports them, keep rows reasonably short, and avoid placing a giant unbreakable row on the page.
  5. Handle long code. Set a print font size, allow wrapping where acceptable, or deliberately permit horizontal overflow for source listings that must remain exact.
  6. Check widows and orphans. These properties improve paragraph endings but cannot override every layout constraint.

Do not force a break after every heading. Excessive forced breaks create nearly empty pages and make small content changes cascade into a different document.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How do I add page numbers or headers and footers to a PDF with CSS?

Page-margin boxes are the standards-oriented mechanism for content in page margins. Support varies substantially. Chrome for Developers documents that Chrome 131 added generated content in page margins by targeting margin at-rules; that milestone does not mean universal support for running headers, footnotes, counters, bleed or all Level 3 features.

@page {
  @top-right {
    content: "Technical guide";
    font-size: 9pt;
    color: #666;
  }

  @bottom-center {
    content: "Page " counter(page) " of " counter(pages);
    font-size: 9pt;
  }
}

Whether this renders depends on the browser or dedicated engine. Test page counters, named pages, left/right selectors and margin content in the exact version used for production. If the target cannot generate reliable running content, put a footer element in the document as a fallback, accept that it will not repeat on every page, or use a pagination engine with documented support.

Does my browser support CSS page-margin boxes?

There is no useful blanket answer such as “supports CSS Paged Media.” Chrome and Firefox support @page according to Chrome’s developer documentation, while individual features have different histories. Chrome 131 is a concrete milestone for generated page-margin content. Browser print settings, fonts, platform, page size and document content can still change output.

  • Pin the browser or renderer version in automated builds.
  • Test with the actual fonts installed or bundled in production.
  • Check print-background and scale settings in the print dialog or headless command.
  • Inspect first, middle and last pages, facing pages, long tables, images and forced breaks.
  • Keep a PDF fixture in CI and compare it when changing CSS or the rendering engine.

A repeatable browser-to-PDF workflow

  1. Define the physical page. Choose size, orientation, margins and whether left/right pages need different geometry.
  2. Separate print presentation. Hide navigation and controls, set readable print colors and remove screen-only decoration inside @media print.
  3. Annotate break decisions. Add classes for chapters, figures and callouts; use modern break properties sparingly.
  4. Render in the target environment. Use the browser version, fonts, locale, viewport and print settings that your users or build server will use.
  5. Inspect the PDF visually and structurally. Look for clipped content, blank pages, missing backgrounds, split headings, orphan lines, unreadable URLs and broken links.
  6. Automate only after visual acceptance. A headless command makes output repeatable, but it does not make unsupported CSS work.

Choosing an output engine

Option Best fit Important constraint
Native browser printing Simple print styles, page size, margins and manageable breaks; maximum fidelity to what users see in a browser Behavior depends on browser implementation and print settings
Paged.js Paginated browser previews and a scriptable HTML/CSS-to-PDF workflow It is a JavaScript polyfill; its CLI uses a headless browser, so browser handling of @page { size } can remain limiting
Prince Workflows needing documented page rules and page-margin regions for headers, footers and other page content Evaluate current compatibility and commercial terms against your requirements
Antenna House Formatter Print-publishing workflows that need a dedicated CSS formatter The cited AH Formatter V6.6 reference is historical; verify the current release and terms directly

Choose by required page features (counters, facing pages, footnotes, specialized regions), browser fidelity, automation and licensing. A dedicated renderer may provide stronger pagination controls, while a browser remains the right choice when matching live web rendering is the priority.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #3
Sale
Web Design with HTML, CSS, JavaScript and jQuery Set
  • Brand: Wiley
  • Set of 2 Volumes
  • A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers

Paged.js in a build

Paged.js paginates in the browser and documents both print styles and a headless-browser CLI path to PDF. A typical workflow is to load your HTML and stylesheet, let pagination complete, then export the resulting document. Treat its output as browser-dependent and test page size, fonts, margin content and breaks in the same environment used by CI.

Performance, reliability and cost considerations

  • Reduce layout surprises: reserve image dimensions, optimize large images and avoid scripts that continually mutate the DOM during capture.
  • Make resources deterministic: bundle or pin fonts and stylesheets, and wait for images and web fonts before printing.
  • Keep documents modular: very long files are easier to debug when chapters can be rendered independently.
  • Measure the right failure: a successful HTTP response can still contain a blank page, missing font or clipped table; inspect rendered pages.
  • Budget for the engine: native printing has no separate renderer license, Paged.js is open source under the MIT license, and commercial engines require checking current pricing and terms directly.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. One request can return PNG, JPEG, WebP or PDF, while its capture pipeline accepts cookie and consent banners and removes more than 60 known consent platforms, newsletter popups and chat widgets before capture. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing status.

For a PDF or image of a URL, use the API documented at https://screenshotneo.com/docs/:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://example.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

It also offers an MCP server for Claude, Cursor and other MCP clients, with take_screenshot, get_page_info and capture_pdf. Features include full-page capture with lazy images loaded, CSS-selector element capture, custom CSS and JavaScript, waiting for selectors or network idle, request blocking, cookies and headers, device presets, PDF margins and page ranges, asynchronous jobs and bulk capture.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is on every plan. Create a free ScreenshotNeo account to try it.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshooting common failures

Everything prints on one continuous sheet

Confirm the print preview is actually using print media and that the target is a paged output. Check that the browser’s paper size and margins are not set to a custom continuous format.

A forced break is ignored

Inspect the element for display: inline, transforms, overflow containers or an ancestor that the engine cannot fragment. Move the break to a block-level wrapper and test break-before: page plus the legacy alias if an older engine is involved.

Headers or page numbers are missing

Verify that the target engine implements the specific margin at-rule and counter you use. Chrome 131’s documented milestone is not evidence of universal support. Remove unsupported rules or switch to a renderer with documented page-margin capabilities.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Images or fonts are absent

Use absolute, reachable URLs or bundle assets, wait for fonts and images before export, and check cross-origin and authentication requirements. Reserve image dimensions to prevent late reflow.

The PDF has unexpected blank pages

Look for consecutive forced breaks, a chapter that already starts after an automatic break, oversized unbreakable blocks or an :left/:right selector forcing a parity page. Remove one constraint at a time.

Content is clipped

Check print scaling, page margins, fixed heights, transforms and overflow. Replace fixed pixel widths with print-friendly widths and allow long URLs or code to wrap where fidelity permits.

Validation checklist

  • Correct paper size and orientation.
  • Margins match the specification and printer-safe area.
  • Every chapter, heading, figure and table starts or splits intentionally.
  • Fonts, colors, backgrounds and images survive PDF export.
  • Page numbers, headers, footers and links work in the target engine.
  • Long content, RTL or non-Latin text, and missing assets have been tested where relevant.
  • The exact browser or renderer version and print settings are recorded for reproducibility.

Frequently Asked Questions

Can CSS guarantee identical PDFs in Chrome, Firefox and a dedicated renderer?

No. The standards define the page model, but implementations differ by feature and version. Validate the engine, fonts, settings and content used for delivery.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

When should I move beyond native browser printing?

Stay with native printing for straightforward page geometry and breaks. Evaluate Paged.js or a dedicated renderer when you need repeatable automation, browser previews, advanced margin content, footnotes, facing-page logic or specialized page regions.

Does break-inside: avoid guarantee that an element stays on one page?

No. It is a fragmentation preference. An element taller than the page, or one constrained by other layout rules, must still split or overflow.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.