Jimmy Breck-McKye

A lazy programmer

A Brief Primer on Print Stylesheets

Browsers do not print background colours

In every browser I know of, the user must explicitly opt-in to printing background colours and images from a web page. There is a webkit-specific CSS rule, -webkit-color-adjust: exact, which overrides this, but no such equivalents for Firefox for IE. Browser vendors want to save their users’ expensive ink.

If a background is an absolute must, you might be able to work around this restriction with using a pseudoelement placed behind the content and clipped using overflow:hidden on the parent. See Appendix 1 below.

Browsers do not print white or light text

Because browsers disable backgrounds in print renders, they have to handle white text that was placed on top of those backgrounds. As such, most browsers will globally coerce text below a certain rgb luminescence to light grey. This can be annoying, particularly if the white text has to appear on top of a coloured element whose background hasn’t been disabled.

SVG/VML element colours are not affected by the above

If you’re generating SVGs (or VMLs in legacy IE), the colours of elements are not affected by the above rules. I suppose you could even potentially implement parts of a print-specific design in SVG with something like Raphael if you really had to. Only do this in a print-specific piece of HTML, though, else you’ll have a lot of potential accessibility difficulties with your interface.

You cannot guarantee that print-specific resources will load before a browser performs a print render

Layout and scaling behaviour is undocumented and idiosyncratic

Webkit upscales physical units

Legacy IE is a nightmare

Print events are unreliable

#

Appendix 1: Force solid background colour to print

Background workaround
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@media print {

  .print-red-background {
      position: relative; /* create absolute positioning context */
      overflow: hidden; /* clip pseudoelement */
  }

  .print-red-background:before {
      content: '';
      position: absolute;
      left: 0;
      right: 0;
      top: 0;
      z-index: -1;
      border-top: 999px solid red;
  }
}

This seems to force a red background to print on a paragraph on at least Chrome and IE11. I haven’t tried it out in other browsers, however. Also note that any white text on this background will appear as grey (see above), so this isn’t really suitable for elements with text.

Comments