Print Stylesheet Recipe
When users print a page, they want a clean, readable document, not screenshots of your nav bar. A small `@media print` block can hide chrome, expand link URLs inline, force black-on-white text, and control page sizing and breaks. Drop these recipes into any project that publishes long-form content (articles, receipts, invoices, recipes).
712 views
10
/* Everything inside @media print only applies when the user prints (or saves
as PDF). Browsers also use this when generating reader-mode print views. */
@media print {
/* Hide site chrome that does not belong in a printed document. */
nav,
header.site,
footer.site,
aside,
.ad,
.cookie-banner,
.skip-link,
.pagination,
.share-buttons {
display: none !important;
}
/* Force readable contrast. Many users still print on monochrome printers,
and even on color printers, dark backgrounds waste ink. */
html,
body {
background: white !important;
color: black !important;
}
/* Use a body font that prints well. Serif faces tend to render crisper at
300 DPI than sans-serif because they were designed for print. */
body {
font-family: Georgia, 'Times New Roman', serif;
font-size: 12pt;
line-height: 1.4;
}
/* Expand link URLs inline so a printed page is not full of "click here". */
a[href]:not([href^="#"]):not([href^="javascript:"])::after {
content: " (" attr(href) ")";
font-size: 0.85em;
color: #444;
}
/* Article images should not break across pages. */
img,
figure,
table {
page-break-inside: avoid;
break-inside: avoid;
}
}The first thing every print stylesheet does is hide the parts of the page that only make sense on screen: navigation, ads, banners, share buttons. Use display: none !important because authors of those components often have specificity high enough to win without the bang. The second job is contrast: many printers are monochrome, and dark mode pages look terrible printed, so force white background and black text. The link-expansion trick (a[href]::after { content: " (" attr(href) ")"; }) prints the URL right after the link text, so the printed copy is still useful as a reference; exclude in-page anchors and javascript: links so you do not get noise. page-break-inside: avoid keeps figures from being cut in half across pages.
@page {
/* @page targets the printed sheet itself, not the document content.
Use it to set paper size and printer margins. */
size: A4 portrait;
margin: 1.5cm;
}
@page :first {
/* Different margins on the title page (smaller top so the heading sits high). */
margin-top: 0.8cm;
}
@media print {
/* Force a page break before each top-level chapter heading.
break-before is the modern alias for page-break-before; both work. */
h1.chapter {
break-before: page;
page-break-before: always;
}
/* Avoid orphaned headings (a heading at the bottom of a page with its
paragraph on the next page). */
h2,
h3,
h4 {
break-after: avoid;
page-break-after: avoid;
}
/* Preserve background colors and gradients on print. By default, browsers
strip these to save ink; set print-color-adjust to keep branded colors
(logos, callout boxes). Use sparingly. */
.brand-callout,
.logo {
print-color-adjust: exact;
-webkit-print-color-adjust: exact;
}
/* Show a footer-like page-number on every printed page (paged-media level 3). */
@page {
@bottom-right {
content: "Page " counter(page) " of " counter(pages);
font-family: Georgia, serif;
font-size: 10pt;
color: #666;
}
}
}The @page rule controls the paper itself: paper size (A4, Letter), orientation (portrait, landscape), and the margins around the printable area. @page :first lets the title page have different margins than subsequent pages. Inside @media print, use break-before: page to force each chapter onto its own page and break-after: avoid on headings so a heading is never the last line on a page. By default, browsers strip background colors and images on print to conserve ink; if your design depends on a colored callout or a printed logo, opt back in with print-color-adjust: exact (and the -webkit- prefix for Safari/Chromium). The nested @page margin boxes (@top-center, @bottom-right) are CSS Paged Media level 3 and let you place running headers and page numbers; support is good in Chromium and Firefox, partial in Safari.
