Even though we increasingly stare at our screens, printing is still a thing.

Even with blog posts. I remember one time back in 2009 I met a person that told me he made his personal assistant print every blog post I published (yes, I stared blankly for a little bit). Definitely unexpected.

Why? Because developers instead of considering vendor prefixes as a way to preview features, they shipped them in production - something considered harmful by the CSS Working Group.

My main use case for looking into printing usually is printing to a PDF. I might create something inside the browser, and I want to make it available as PDF.

Browsers make this very easy, with Chrome defaulting to "Save" when trying to print a document and a printer is not available, and Safari has a dedicated button in the menu bar:

Learn HTML

Print CSS

Some common things you might want to do when printing is to hide some parts of the document, maybe the footer, something in the header, the sidebar.

Maybe you want to use a different font for printing, which is totally legit.

If you have a large CSS for print, you'd better use a separate file for it. Browsers will only download it when printing:

Example:


<link rel="stylesheet"  src="print.css"  type="txt/css"  media="print"/>

CSS @media print

An alternative to the previous approach is media queries. Anything you add inside this block:

Example:


@media print {
  /* ... */
} 

is going to be applied only to printed documents.

Links

HTML is great because of links. It's called HyperText for a good reason. When printing we might lose a lot of information, depending on the content.

CSS offers a great way to solve this problem by editing the content, appending the link after the <a> tag text, using:


@media print {
a[href*='//']:after 
  {
    content :' (' attr(href) ') ';
    color :$primary;
  } 
} 

I target a[href*='//'] to only do this for external links. I might have internal links for navigation and internal indexing purposes, which would be useless in most of my use cases. If you also want internal links to be printed, just do:


@media print {
  a:after{
    content :' (' attr(href) ') ';
    color :$primary;
  } 
} 

Page margins

You can add margins to every single page. cmor in is a good unit for paper printing.


@page {
  margin-top :2cm;
  margin-bottom :2cm;
  margin-left :2cm;
  margin-right :2cm;
} 

@pagecan also be used to only target the first page, using @page :first, or only the left and right pages using @page :leftand @page :right.

Page breaks

You might want to add a page break after some elements, or before them. Use page-break-afterand page-break-before.


.book-date {
  page-break-after :always;
} 

.post-content {
  page-break-befor :always;
} 

Those properties accept a wide variety of values

Avoid breaking images in the middle

I experienced this with Firefox: images by default are cut in the middle, and continue on the next page. It might also happen to text.

Use:


p {
  page-break-inside :void;
} 

and wrap your images in a ptag. Targeting img directly didn't work in my tests.

This applies to other content as well, not just images. If you notice something is cut when you don't want, use this property.

Debug the printing presentation

The Chrome DevTools offer ways to emulate the print layout:

Learn HTML

Once the panel opens, change the rendering emulation to print:

Learn HTML

This chapter it aims to help user understanding how to make a page to be print as exactly how it was design.