CSS Tip: Style your Radio Buttons and Checkboxes for Printing

One common mistake when developing these custom components: forgetting about the printing styles.

We are discussing web design and development, and I am talking about printing. What is this, the 20th century? Who prints a website nowadays? Who even owns a printer?

The answer to many of those questions may surprise you. According to Deloitte, 62% of American households have a printer (based on a Consumer Technology Association report from 2020). And the British marketing agency Varn ran some original research and found that around 50% of their clients printed websites.

But let's put printers aside. Long gone are the days in which people printed map directions or recipes. Now, printing doesn't necessarily imply paper. Many people save websites as PDFs for their records (e.g., of form answers or receipts). They may never print those PDFs into paper, but the styles applied to the documents are the website's printing styles.

What does this have to do with design and web development again? Often, developers share their customized versions of native components and design systems, and we can find many issues when printing them, especially with elements like radio buttons or checkboxes.

I'm going to focus on those components. A common way to create custom radios and checkboxes is by using backgrounds. They are easy to implement, they look good, and they are supported everywhere… or almost. But there's a problem: browsers do not print backgrounds by default.

You could add @media print to specify printer-specific styles, and that will work for many things, but it can get messy –or not make sense– fast:

input[type="checkbox"] {
  appearance: none;
  border: 1px solid #666;
  border-radius: 0.125rem;
  box-shadow: inset 0 0 0 0.125rem #fff;
  display: inline-block;
  height: 1rem;
  width: 1rem;
  vertical-align: bottom;
}

input[type="checkbox"]:checked {
  background: blue;
}

@media print {
  input[type="checkbox"]:checked {
    text-align: center;
  }

  input[type="checkbox"]:checked::before {
    content: "x";
  }
}

This method will work and will be supported by all browsers, modern and old (looking at Internet Explorer, which we shouldn't care about much anymore, but you never know.)

But there is a better way (and it's simpler, too!). Something that will make it nicer and more custom… because it will respect your styles both on the screen and on paper (or PDF). It is print-color-adjust:

The print-color-adjust property provides a hint to the user-agent about how it should treat color and style choices that might be expensive or generally unwise on a printer or similar device, such as using light text on a dark background.

With this property, we can specify if we want the printer to include background colors and all the styles so that elements look the same on paper as they look on the screen. Or let the browser make a choice for us (which will lead to differences in color and format.)

print-color-adjust has two key values:

  • economy: the browser will make the adjustments that are considered necessary to save resources. For example, removing the backgrounds to avoid unnecessary ink usage. This is the default value.

  • exact: this tells the browser that the backgrounds and colors in the design are essential and must be printed without change (users will still have some input in the printing form, though.)

In the example of the radio buttons and checkboxes, it is essential to have the backgrounds to indicate whether they are selected. No need for messy @media print or hacky solutions. One CSS property and we are good to go:

input[type="checkbox"] {
  appearance: none;
  border: 1px solid #666;
  border-radius: 0.125rem;
  box-shadow: inset 0 0 0 0.125rem #fff;
  display: inline-block;
  height: 1rem;
  width: 1rem;
  vertical-align: bottom;
  -webkit-print-color-adjust: exact;
  print-color-adjust: exact;
}

input[type="checkbox"]:checked {
  background: blue;
}

One small catch of this solution is that not all browsers support the property name print-color-adjust. One good thing: using the -webkit prefix will cover all desktop browsers (not so good on mobile, though):

Screen capture of caniuse.com for print-color-adjust

The recommendation is to use the property sparingly and only where needed. Otherwise, we may end up with some angry users/customers. But in the case of the checkboxes and radio buttons, it is necessary and a tool that will simplify our code.


To provide a complete experience, we must design and develop for that whole experience. And that includes printing. Components not only need to look good on the screen, but they must also be usable and accessible, both on the screen and in print.

Did you find this article valuable?

Support Alvaro Montoro by becoming a sponsor. Any amount is appreciated!