CSS Print Styles Table
| Piece | What it does | Field note |
|---|---|---|
@media print | The print stylesheet | Hide nav/ads, expand content - the second layout that always exists |
break-inside: avoid | Keep blocks whole | Cards, rows and figures survive page breaks |
break-before: page | Force new pages | Sections start clean - the chapter break |
print-color-adjust: exact | Keep the colors | Browsers strip backgrounds by default - exact forces them |
a::after content attr(href) | Print the URLs | Links are useless on paper - show where they go |
@page margins | The paper box | @page { margin: 2cm } - the printable area, per page |
details[open] forcing | Collapsed content prints | Force-open accordions or their answers vanish on paper |
beforeprint / afterprint | JS at print time | Swap views, re-render charts for the paper width |
A print stylesheet is the second layout every content page silently needs: @media print hides navigation and ads, break-inside: avoid keeps cards and table rows whole across page breaks, and print-color-adjust: exact stops browsers from stripping backgrounds (the default saves ink).
Bottom line: links die on paper - show their URLs via a::after { content: attr(href) }. Force details[open] or accordion answers vanish in print. And beforeprint/afterprint events let JavaScript re-render charts for the paper width before the page hits the tray.
The honest part: receipts, recipes, invoices and itineraries are the pages users actually print - and they print them from the SAME URL, so the print layout is not a separate product but a mode of the existing page that deserves the same care as mobile.
How to use
- Strip the chrome: @media print { nav, .ads, .sidebar { display: none } } - the article is the product on paper; everything else is layout debt.
- Keep blocks whole: .card, tr, figure { break-inside: avoid; } and h2 { break-after: avoid; } - headings never strand at page bottoms.
- Reveal link destinations: @media print { a::after { content: ' (' attr(href) ')'; } } scoped to article links - the reference survives the paper.
Frequently asked questions
Why do backgrounds and colors vanish when printing?
Ink economy, by default. Browsers strip background colors and images when printing unless the page opts in with print-color-adjust: exact (the legacy name -webkit-print-color-adjust) - because full-bleed dark themes would drain toner for no readable gain. The opt-in is per-element and should be intentional: keep it for receipts, brand headers and color-coded status badges that lose meaning in black-and-white; let it stay stripped for large decorative surfaces. The deeper design point: a print stylesheet built on text-and-borders (not background color) prints correctly everywhere, and color becomes the enhancement.
How do page breaks actually get controlled?
The break-* family, applied to the boxes. break-inside: avoid on cards, table rows and figures keeps each whole across the page boundary; break-before: page forces a new sheet (section = chapter); break-after: avoid on headings prevents a heading stranding at a page bottom with its content on the next page. The legacy names (page-break-inside etc.) still work everywhere. The print-specific trap: an element only breaks where layout allows - a 1.5-page-tall unbreakable block forces early breaks and blank space, so avoid-groups need to be smaller than a page to be honored.
Why do collapsed accordions and tabs print empty?
Because printers render the CURRENT layout, and hidden is hidden on paper too. A closed details element's answers, an unselected tab panel's content - display: none means nothing prints, and the user gets a page with questions but no answers. The fixes: force-open in print CSS (details[open]-forcing is not possible in pure CSS for closed details, so a beforeprint event listener that sets open, reverted in afterprint, is the standard pattern), or design print-critical content without hiding mechanisms - the details table's print note exists precisely for this. The general rule: whatever the screen hides, the paper loses; decide per content whether print should reveal it.
When is JavaScript at print time actually needed?
When the print output must DIFFER from any on-screen state, not just be filtered. beforeprint and afterprint events fire around the browser's print dialog: use beforeprint to re-render charts at fixed paper width (canvas charts sized for the screen print at wrong scales), expand all collapsed sections, swap infinite-scroll placeholders for full data, and afterprint to restore the live view. CSS handles hiding, breaking and color; JS handles the STATE changes CSS cannot express. The pattern pairs with window.matchMedia('print') for frameworks that render declaratively - the listener pattern is the imperative escape hatch.