← All posts

Tutorials

Fix bad printing: a custom @media print stylesheet for any site

You hit Ctrl+P on a long article and the preview is a disaster: the navigation bar eats the first page, the sidebar overlaps the text, a cookie bar floats over paragraph three, and a solid dark background is about to drain your printer cartridge. The site just never wrote a print stylesheet. So write one yourself — it lives in a JustZix CSS rule and it makes "Save as PDF" usable again.

Why most sites print badly

Printing is the most ignored part of web development. Designers test on screens; QA tests on screens; nobody opens the print preview. The result is that a huge share of the web has either no @media print block at all, or one written years ago that no longer matches the layout. The browser then prints the screen layout as-is — fixed headers, multi-column grids, dark themes and all.

The fix is a CSS rule that only applies when the page is being printed. Everything inside @media print { ... } is invisible on screen and only kicks in for paper and PDF export. That means you can be aggressive: hide whole regions, recolor everything, force single-column — none of it touches normal browsing.

Step 1 — hide everything that is not content

Navigation, sidebars, footers, share widgets, cookie bars, sticky "subscribe" boxes: none of it belongs on paper. Start by hiding the obvious chrome.

@media print {
  header, nav, aside, footer,
  .sidebar, .site-header, .site-footer,
  .cookie-banner, .newsletter, .share-bar,
  .ad, [class*="advert" i], [id*="cookie" i],
  [role="banner"], [role="navigation"],
  [aria-label*="cookie" i] {
    display: none !important;
  }
}

If the page still prints junk, open the print preview, find the offending block in DevTools, and add its selector to the list. You only need to do this once per site — the rule is saved.

Step 2 — expand truncated content

Many sites clamp text to a few lines, hide overflow, or put the article in a fixed-height scrolling box. On screen that is fine; on paper it cuts your content off. Undo the clamping.

@media print {
  /* Kill height limits and scroll boxes */
  main, article, .content, .post-body {
    height: auto !important;
    max-height: none !important;
    overflow: visible !important;
  }

  /* Undo line-clamp truncation */
  * {
    -webkit-line-clamp: unset !important;
    overflow: visible !important;
  }

  /* Force the article full width, drop the grid */
  body, main, article {
    display: block !important;
    width: 100% !important;
    max-width: 100% !important;
    margin: 0 !important;
    float: none !important;
  }
}

The blanket overflow: visible on * looks heavy-handed, but inside @media print it is exactly what you want — nothing should be clipped on a printout.

Step 3 — control page breaks

The single biggest improvement to a printout is stopping things from breaking across pages mid-element. A code block split over two sheets, a heading stranded at the bottom of a page, a table row torn in half — all fixable with the fragmentation properties.

@media print {
  /* Never split these across a page */
  pre, blockquote, table, figure, img,
  li, .card {
    break-inside: avoid;
  }

  /* Keep a heading with the text that follows it */
  h1, h2, h3, h4 {
    break-after: avoid;
  }

  /* Start each top-level section on a fresh page */
  .chapter, section.page {
    break-before: page;
  }
}

The modern properties are break-inside, break-before and break-after. The old page-break-* names still work and Chrome maps them automatically, but write the new ones for new rules.

Step 4 — show link URLs after anchors

A printed link is useless — the reader cannot click "click here". Print the actual URL next to it using a generated-content trick.

@media print {
  a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 0.85em;
    color: #555;
    word-break: break-all;
  }

  /* Don't print URLs for in-page anchors or javascript: links */
  a[href^="#"]::after,
  a[href^="javascript:"]::after {
    content: "";
  }
}

This pulls the href attribute into visible text. Skip it for anchor links and image links if it gets noisy — a printout full of long tracking URLs is its own kind of mess.

Step 5 — set margins with @page

The @page rule controls the printed sheet itself: its margins and size. Browsers also let you set margins in the print dialog, but baking them into the rule means every print of that site is consistent.

@media print {
  @page {
    margin: 18mm 16mm;
    size: A4;
  }

  /* Tighter margin on the first page if you have a title block */
  @page :first {
    margin-top: 12mm;
  }
}

Step 6 — force a light background to save ink

Dark-themed sites print as a wall of toner. By default Chrome strips background colors when printing (unless "Background graphics" is ticked), but text often stays light gray on the assumption of a dark backdrop. Force a clean black-on-white.

@media print {
  html, body, * {
    background: #fff !important;
    background-image: none !important;
    color: #000 !important;
    box-shadow: none !important;
    text-shadow: none !important;
  }

  /* Keep images and real photos intact */
  img, svg, video { filter: none !important; }

  /* Slightly soften secondary text so it still reads as secondary */
  .muted, .meta, time, small { color: #444 !important; }
}

This guarantees readable, ink-cheap output regardless of the site's theme — and it pairs well with turning off "Background graphics" in the print dialog.

Putting it together in JustZix

  1. Create a rule scoped to the site you print from often — for example https://docs.example.com/*.
  2. Paste all six blocks into the CSS pane, wrapped in one @media print (or keep separate blocks — both work).
  3. Open the page, hit Ctrl+P, and watch the preview. Iterate: anything still wrong gets a selector added.
  4. Sync your key so the same clean print setup follows you to every device.

Because the whole thing sits inside @media print, you can leave the rule active permanently. It is dormant during normal browsing and only wakes up when you print or export a PDF.

Pitfalls worth knowing

See also

A good print stylesheet is a one-time, fifteen-minute job that pays off every single time you save a PDF. Install JustZix, scope a rule to your most-printed site, and never fight the print preview again.

Rate this post

No ratings yet — be the first.

Try it yourself

Install JustZix and paste any snippet from this article. Two minutes from zero to a working rule across all your devices.

Get JustZix

Features · How it works · Examples · Use cases