Print & PDF HTML
print & pdf html print and pdf html uses paged media css, semantic tables with repeat headers, pr print and
Introduction
Print and PDF HTML targets paged media: invoices, reports, shipping labels, and regulatory filings rendered via browser print, headless Chrome, or wkhtmltopdf. @page rules, break-inside, and print-specific markup differ sharply from screen CSS — page breaks in wrong places invalidate legal documents.
Business problem
Business pressure: Generated PDF invoice cut table rows across pages — finance rejected batch. Or print stylesheet hid terms on legal contract PDF — compliance failure. Print HTML errors are silent until customers or auditors complain.
- Legal: Statements and disclosures must paginate correctly with headers/footers.
- Ops: Warehouse pick lists must print reliably on thermal printers from HTML.
- Brand: PDF proposals are sales artifacts — broken layout loses deals.
Why this feature exists
Platform motivation: HTML-to-PDF reuse web skills for document generation vs proprietary formats. Browsers implement CSS Paged Media subset — engineers must know what headless Chrome supports vs browser print dialog.
- History: print.css → Puppeteer/Playwright PDF → dedicated PDF libs when HTML insufficient.
- Alternative rejected: Screen-only CSS on PDF route — page breaks chaos.
- Modern role: Separate print template route with @media print or dedicated /pdf HTML shell.
Browser internals
Inside the engine: Print layout engine paginates DOM into pages. break-before/after/inside control fragmentation. Fixed position elements repeat as headers/footers in some engines. Background graphics may be suppressed unless user enables — use -webkit-print-color-adjust for brand colors.
- Fonts: Embed or use system stacks — webfont fail in headless if not loaded before PDF call.
- Viewport: PDF generation uses paper size not screen width — separate @page size.
Rendering workflow
Rendering path: Server renders print HTML URL → headless browser printToPDF with waitUntil networkidle → PDF stored/sent. Or user triggers window.print() with @media print stylesheet linked from screen page.
- Wait: await page.waitForFont ready before PDF — prevents layout shift in output.
- Margin: @page margin box for running headers with counter(page).
Feature deep dive
Print markup patterns: Semantic tables for tabular data (repeat thead on each page), avoid break-inside on tr where supported, page-break-after on chapter sections, print-only blocks with class hidden on screen.
- @page: size: A4; margin: 20mm;
- Running elements: Limited support — test in target engine.
- Links: Optional print footnote with href URL after link text.
@media print {@page { size: A4; margin: 15mm; }thead { display: table-header-group; }tr, img { break-inside: avoid; }.no-print { display: none !important; }a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 0.8em; }}
Accessibility analysis
A11y architecture: PDF/UA requires tagged PDF for screen readers — HTML → PDF via Chrome may not produce fully tagged PDF; use Prince XML or post-process when compliance mandates. Print HTML still needs logical heading order for remediation workflows.
- Contrast: Print grayscale may fail contrast — test monochrome preview.
SEO impact
SEO architecture: Print routes often noindex — <meta name="robots" content="noindex"> on /invoice/pdf templates. Prevent duplicate content from printable URLs indexed.
- Canonical: Printable version canonical to main article if public.
Security considerations
Security boundary: PDF generation SSRF if URL parameter accepts arbitrary URLs in headless service. Authenticate print routes — invoices contain PII. Watermark sensitive PDFs in HTML layer.
- PII: PDF cached at CDN — use short-lived signed URLs, noindex, no cache headers.
Performance impact
Performance: Headless PDF is CPU heavy — queue workers, not sync request on hot path unless cached. HTML complexity (deep nesting) slows print layout — simplify DOM for batch invoices.
- Cache: Immutable invoice PDF keyed by id after generation.
Real production example
Production pattern: Stripe-style invoices: dedicated print HTML template, Puppeteer microservice, fonts self-hosted, regression test compares PDF hash weekly against golden file for template changes.
- Labels: Separate 4×6 HTML template for shipping — @page size custom.
Enterprise usage
Enterprise: ERP generates 10k nightly PDF statements — HTML template version in footer, batch worker pool, archival to WORM storage. Legal signs off on print CSS for contract boilerplate pagination.
- Localization: Per-locale @page margin for address blocks.
Common production failures
What breaks in prod: Flex layout caused row split mid-cell in PDF. Webfont timeout — PDF used fallback and overflow clipped totals. Public /print URL indexed — leaked sample invoice data in snippet.
- Incident: color-adjust not set — logos disappeared in print; fixed in print CSS.
Architecture review questions
- Does thead repeat on multi-page tables?
- Are no-print nav elements hidden in @media print?
- PDF engine waitFor fonts/network before capture?
- Print URLs authenticated and noindex?
Hands-on project
Project: Build invoice HTML with @media print, generate PDF via Playwright, verify table row does not split across pages.
- Deliverable: HTML, print CSS, PDF sample, golden hash test.
Interview questions
How do you prevent table rows splitting across PDF pages?(Advanced)
Use semantic table with thead display table-header-group, break-inside avoid on tr/td where engine supports, simplify layout avoid flex for critical rows, test in target headless engine not only browser print preview.
Follow-up: When would you abandon HTML-to-PDF for a native PDF library?
Try it yourself
Edit the HTML, CSS, or JS panels — the preview updates as you type.
Try it yourself
Summary
Print and PDF HTML uses paged media CSS, semantic tables with repeat headers, print-only templates, and headless browser generation with golden-file regression — treating documents as engineered outputs, not screen pages printed as-is.