CSS for Print Media

Introduction to Print Stylesheets

Print stylesheets allow you to optimize web content for printing, creating a better experience for users who need physical copies of your content. A well-designed print stylesheet can save ink, paper, and user frustration.

Why Print Stylesheets Matter

  • Accessibility: Many users still need to print web content for various reasons
  • Resource Efficiency: Properly formatted print layouts save ink and paper
  • Professionalism: Well-formatted printed documents reflect well on your brand
  • User Experience: Prevents frustration when users need to print your content

Common Print Use Cases

  • Articles and blog posts
  • Recipes
  • Invoices and receipts
  • Tickets and boarding passes
  • Directions and maps
  • Reference materials
  • Contracts and legal documents

Creating Print Stylesheets

Using Media Queries

Print stylesheets are typically implemented using the print media query:


/* Method 1: Separate stylesheet */
<link rel="stylesheet" href="styles.css" media="screen">
<link rel="stylesheet" href="print.css" media="print">

/* Method 2: Media query in main stylesheet */
@media print {
  /* Print-specific styles */
  body {
    font-size: 12pt;
    line-height: 1.5;
    color: #000;
    background: #fff;
  }
}
                        

Basic Print Reset

Start with a basic reset for print media:


@media print {
  /* Reset background colors to white and text to black */
  body, article {
    width: 100%;
    margin: 0;
    padding: 0;
    background: #fff;
    color: #000;
  }
  
  /* Set appropriate font size and line height */
  body {
    font-size: 12pt;
    line-height: 1.5;
    font-family: "Times New Roman", Times, serif;
  }
  
  /* Hide non-essential elements */
  nav, aside, footer, .ad, .no-print, 
  button, .button, .nav-bar, .menu {
    display: none !important;
  }
  
  /* Ensure the main content takes full width */
  main, article, .content {
    width: 100%;
    display: block;
  }
  
  /* Reset all colors to print-friendly values */
  * {
    background-color: transparent !important;
    color: #000 !important;
    box-shadow: none !important;
    text-shadow: none !important;
    filter: none !important;
  }
}
                        

Typography for Print

Font Considerations


@media print {
  /* Use serif fonts for better readability in print */
  body {
    font-family: "Times New Roman", Times, Georgia, serif;
  }
  
  /* Set appropriate sizes */
  h1 { font-size: 24pt; }
  h2 { font-size: 18pt; }
  h3 { font-size: 14pt; }
  p, li { font-size: 12pt; }
  
  /* Ensure adequate contrast */
  * { color: #000 !important; }
  
  /* Avoid very light text that won't print well */
  .text-light, .text-white {
    color: #000 !important;
  }
}
                        

Links and References


@media print {
  /* Make links black but keep underline */
  a {
    color: #000 !important;
    text-decoration: underline;
  }
  
  /* Show URL after link text */
  a[href]:after {
    content: " (" attr(href) ")";
    font-size: 90%;
  }
  
  /* Don't show URL for internal links or javascript */
  a[href^="#"]:after,
  a[href^="javascript:"]:after {
    content: "";
  }
  
  /* Alternative: footnote style for URLs */
  article {
    counter-reset: footnote;
  }
  
  a[href]:not([href^="#"]):not([href^="javascript:"]) {
    counter-increment: footnote;
  }
  
  a[href]:not([href^="#"]):not([href^="javascript:"]):after {
    content: " [" counter(footnote) "]";
    font-size: 90%;
    vertical-align: super;
  }
  
  /* Add a URL list at the end */
  article:after {
    content: "References:";
    display: block;
    margin-top: 2em;
    border-top: 1px solid #000;
    padding-top: 1em;
    font-weight: bold;
  }
}
                        

Page Layout Control

Page Breaks

Control where page breaks occur in printed documents:


@media print {
  /* Avoid page breaks inside these elements */
  h1, h2, h3, h4, h5, h6, img, table, figure, blockquote {
    page-break-inside: avoid;
  }
  
  /* Ensure headings aren't printed at the bottom of a page */
  h1, h2, h3, h4, h5, h6 {
    page-break-after: avoid;
  }
  
  /* Force page breaks before new sections */
  section, .page-break {
    page-break-before: always;
  }
  
  /* Modern CSS properties (with better browser support) */
  h1, h2, h3, h4, h5, h6, img, table, figure, blockquote {
    break-inside: avoid;
  }
  
  h1, h2, h3, h4, h5, h6 {
    break-after: avoid;
  }
  
  section, .page-break {
    break-before: page;
  }
  
  /* Control orphans and widows */
  p {
    orphans: 3; /* Min lines at bottom of page */
    widows: 3;  /* Min lines at top of page */
  }
}
                        

Page Size and Margins


@media print {
  /* Set page size */
  @page {
    size: letter; /* Can be letter, legal, A4, A5, etc. */
    margin: 2cm; /* Default margin for all sides */
  }
  
  /* Different margins for different sides */
  @page {
    margin-top: 2cm;
    margin-right: 1.5cm;
    margin-bottom: 2cm;
    margin-left: 1.5cm;
  }
  
  /* Named pages for different sections */
  @page title {
    margin-top: 3cm;
  }
  
  .title-page {
    page: title;
  }
  
  /* First page special treatment */
  @page :first {
    margin-top: 3cm;
  }
  
  /* Left and right pages (for book-style printing) */
  @page :left {
    margin-left: 2cm;
    margin-right: 1cm;
  }
  
  @page :right {
    margin-left: 1cm;
    margin-right: 2cm;
  }
}
                        
Note: While the @page rule is part of the CSS specification, browser support varies. Basic margin settings are well-supported, but more advanced features like named pages may not work in all browsers.

Images and Media

Image Handling


@media print {
  /* Ensure images are sized appropriately */
  img, svg, figure {
    max-width: 100% !important;
    page-break-inside: avoid;
    break-inside: avoid;
  }
  
  /* Improve image quality for print */
  img {
    -webkit-print-color-adjust: exact !important;
    color-adjust: exact !important;
    print-color-adjust: exact !important;
  }
  
  /* Handle background images */
  .hero-image {
    -webkit-print-color-adjust: exact !important;
    color-adjust: exact !important;
    print-color-adjust: exact !important;
  }
  
  /* Alternative text for images that might not print well */
  .background-image:after {
    content: "Image: " attr(alt);
    display: block;
    font-style: italic;
    font-size: 0.9em;
  }
}
                        

Tables


@media print {
  /* Ensure tables print properly */
  table {
    width: 100%;
    border-collapse: collapse;
    page-break-inside: avoid;
    break-inside: avoid;
  }
  
  /* Add visible borders for print */
  th, td {
    border: 1px solid #000;
    padding: 0.25cm;
    text-align: left;
  }
  
  /* Repeat table headers on each page */
  thead {
    display: table-header-group;
  }
  
  /* Repeat table footers on each page */
  tfoot {
    display: table-footer-group;
  }
  
  /* Ensure adequate contrast for table cells */
  tr, th, td {
    background-color: transparent !important;
    color: black !important;
  }
  
  /* Add alternating row colors that print well */
  tr:nth-child(even) {
    background-color: #f2f2f2 !important;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
}
                        

Headers, Footers, and Page Numbers

Running Headers and Footers

Create headers and footers that appear on every printed page:


@media print {
  /* Method 1: Using fixed positioning */
  .print-header {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: 1cm;
    border-bottom: 1px solid #000;
    text-align: center;
  }
  
  .print-footer {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    height: 1cm;
    border-top: 1px solid #000;
    text-align: center;
  }
  
  /* Add padding to main content to avoid overlap */
  body {
    padding-top: 1.5cm;
    padding-bottom: 1.5cm;
  }
  
  /* Method 2: Using @page and running elements (limited support) */
  @page {
    @top-center {
      content: "Company Name";
    }
    @bottom-center {
      content: "Page " counter(page) " of " counter(pages);
    }
  }
}
                        

Custom Page Numbers


@media print {
  /* Method 1: JavaScript-generated page numbers */
  /* Add this element to your HTML */
  /* 
*/ .page-number:before { content: "Page " counter(page); } .page-number { position: fixed; bottom: 0.5cm; right: 0.5cm; font-size: 10pt; } /* Method 2: CSS-only page numbers (experimental, limited support) */ @page { @bottom-right { content: "Page " counter(page) " of " counter(pages); } } /* Method 3: Pseudo-element on the body */ body:after { content: "Page " counter(page); counter-increment: page; position: fixed; bottom: 0.5cm; right: 0.5cm; font-size: 10pt; } }
Browser Support Note: The @page margin boxes (like @top-center) and counters like counter(pages) have limited browser support. For maximum compatibility, use the fixed positioning method and consider using JavaScript to generate page numbers if needed.

Advanced Print Techniques

Print-Only Content


/* Hide elements on screen but show them in print */
.print-only {
  display: none;
}

@media print {
  .print-only {
    display: block;
  }
}

/* Example: Print-only header with logo and date */
<div class="print-only print-header">
  <img src="logo.png" alt="Company Logo">
  <div class="print-date">Printed on: <script>document.write(new Date().toLocaleDateString())</script></div>
</div>
                        

QR Codes for Print


/* Add QR codes to printed documents to bridge print and digital */
.document-qr {
  display: none;
}

@media print {
  .document-qr {
    display: block;
    float: right;
    width: 2cm;
    height: 2cm;
    margin: 0.5cm;
  }
  
  .qr-caption {
    font-size: 8pt;
    text-align: center;
    margin-top: 0.2cm;
  }
}

/* Example HTML */
<div class="document-qr">
  <img src="https://api.qrserver.com/v1/create-qr-code/?size=150x150&data=https://example.com/doc/123" alt="QR Code">
  <div class="qr-caption">Scan for digital version</div>
</div>
                        

Print Preview Button


/* Add a print button to your page */
.print-button {
  display: inline-block;
  padding: 10px 20px;
  background-color: #f0f0f0;
  border: 1px solid #ddd;
  border-radius: 4px;
  cursor: pointer;
}

.print-button:hover {
  background-color: #e0e0e0;
}

@media print {
  .print-button {
    display: none;
  }
}

/* JavaScript to trigger print */
document.querySelector('.print-button').addEventListener('click', function() {
  window.print();
});
                        

Print-Friendly Design Patterns

Article/Blog Post


@media print {
  /* Hide navigation, sidebar, comments, etc. */
  nav, .sidebar, .comments, .related-posts, .social-share {
    display: none !important;
  }
  
  /* Expand content to full width */
  .article, .post, main {
    width: 100% !important;
    margin: 0 !important;
    padding: 0 !important;
  }
  
  /* Improve typography */
  .article-title {
    font-size: 24pt;
    margin-bottom: 0.5cm;
  }
  
  .article-meta {
    font-size: 10pt;
    color: #666 !important;
    margin-bottom: 1cm;
  }
  
  .article-content {
    font-size: 12pt;
    line-height: 1.5;
  }
  
  /* Handle images */
  .article-content img {
    max-width: 100%;
    margin: 1cm 0;
  }
  
  /* Add source URL at the end */
  .article-content:after {
    content: "Source: " attr(data-source-url);
    display: block;
    margin-top: 1cm;
    font-size: 10pt;
    color: #666 !important;
  }
}
                        

Recipe


@media print {
  /* Hide non-essential elements */
  .recipe-rating, .recipe-comments, .recipe-video, .ads {
    display: none !important;
  }
  
  /* Layout for recipe */
  .recipe-header {
    text-align: center;
    margin-bottom: 1cm;
  }
  
  .recipe-title {
    font-size: 20pt;
    margin-bottom: 0.3cm;
  }
  
  .recipe-meta {
    font-size: 10pt;
    color: #666 !important;
  }
  
  /* Two-column layout for ingredients and instructions */
  .recipe-content {
    display: flex;
    flex-direction: row;
    gap: 1cm;
  }
  
  .recipe-ingredients {
    flex: 1;
    border: 1px solid #000;
    padding: 0.5cm;
    break-inside: avoid;
  }
  
  .recipe-instructions {
    flex: 2;
  }
  
  /* Checkboxes for ingredients */
  .recipe-ingredient {
    display: flex;
    align-items: baseline;
    margin-bottom: 0.2cm;
  }
  
  .recipe-ingredient:before {
    content: "□";
    margin-right: 0.2cm;
    font-size: 14pt;
  }
  
  /* Numbered instructions */
  .recipe-step {
    margin-bottom: 0.5cm;
    break-inside: avoid;
  }
}
                        

Invoice/Receipt


@media print {
  /* Clean layout */
  .invoice {
    font-family: Arial, sans-serif;
    color: #000 !important;
    padding: 1cm;
  }
  
  /* Header with logo and invoice info */
  .invoice-header {
    display: flex;
    justify-content: space-between;
    margin-bottom: 1cm;
  }
  
  .invoice-logo {
    max-height: 2cm;
  }
  
  .invoice-info {
    text-align: right;
  }
  
  .invoice-id {
    font-size: 16pt;
    font-weight: bold;
  }
  
  /* Customer and company details */
  .invoice-addresses {
    display: flex;
    justify-content: space-between;
    margin-bottom: 1cm;
  }
  
  .invoice-address {
    width: 45%;
  }
  
  /* Line items table */
  .invoice-items {
    width: 100%;
    border-collapse: collapse;
    margin-bottom: 1cm;
  }
  
  .invoice-items th, .invoice-items td {
    border: 1px solid #000;
    padding: 0.2cm;
  }
  
  .invoice-items th {
    background-color: #f0f0f0 !important;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  
  /* Totals */
  .invoice-totals {
    width: 50%;
    margin-left: auto;
  }
  
  .invoice-total-row {
    display: flex;
    justify-content: space-between;
    margin-bottom: 0.2cm;
  }
  
  .invoice-grand-total {
    font-weight: bold;
    font-size: 14pt;
    border-top: 1px solid #000;
    padding-top: 0.2cm;
  }
  
  /* Footer */
  .invoice-footer {
    margin-top: 2cm;
    font-size: 9pt;
    text-align: center;
    color: #666 !important;
  }
}
                        

Testing Print Stylesheets

Browser Print Preview

The simplest way to test print styles is using the browser's print preview:

  • Chrome: Ctrl+P or Cmd+P
  • Firefox: Ctrl+P or Cmd+P
  • Safari: Cmd+P
  • Edge: Ctrl+P

DevTools Emulation

Modern browsers allow you to emulate print media in developer tools:

  1. Open DevTools (F12 or Right-click > Inspect)
  2. In Chrome, click the three dots > More tools > Rendering
  3. Under "Emulate CSS media type", select "print"

Common Print Issues to Check

  • Content Overflow: Ensure content fits within page boundaries
  • Page Breaks: Check that page breaks occur at appropriate places
  • Color and Contrast: Ensure text is readable when printed in black and white
  • Links: Verify that URLs are visible for important links
  • Images: Check that images print at appropriate sizes and quality
  • Background Colors/Images: Test if they print as expected (may require user settings)
Pro Tip: Test your print styles on different browsers and with different paper sizes. Print behavior can vary significantly between browsers and printer settings.

Best Practices

Performance Considerations

  • Separate Print Stylesheet: Consider using a separate print stylesheet to avoid loading print styles on screen
  • Avoid @import: Don't use @import in print stylesheets as it can delay loading
  • Optimize Images: Provide optimized versions of images for print if necessary

Accessibility

  • Contrast: Ensure adequate contrast for text and background
  • Font Size: Use appropriate font sizes (minimum 12pt for body text)
  • Alternative Text: Provide text alternatives for complex visuals
  • Linearize Content: Ensure content makes sense when linearized for print

Sustainability

  • Ink Conservation: Use lighter colors and avoid large dark backgrounds
  • Page Efficiency: Optimize layout to reduce the number of pages needed
  • Print Selection: Allow users to select which parts of the content to print
  • Digital Alternatives: Offer PDF download as an alternative to printing
Final Tip: Remember that print stylesheets are often overlooked but can significantly improve user experience. A small investment in print styles can make a big difference for users who need to print your content.