🚀AdvancedDocument Output

HTML for Print

Optimize your HTML pages for printing using print media queries, @page rules, and semantic HTML structure that produces clean print layouts.

Overview

Every web page is potentially printable and many users will print invoices, reports, articles, and documentation from your site. Designing for print requires CSS `@media print` queries to show/hide elements, `@page` rules to control page size and margins, and careful HTML structure to control where content breaks across pages. Key strategies: hide navigation, sidebars, ads, and other screen-only UI; expand links to show their href; ensure text is black on white; control page breaks with CSS properties; and use semantic HTML (article, section, h1-h6, p) so the browser can make intelligent break decisions. For complex print outputs (PDFs, receipts, reports), consider server-side PDF generation. But for general printability, CSS media queries are highly capable and require no server-side work.

Key Points

  • •`@media print { ... }` CSS rules that only apply when printing
  • •`@page { margin: 2cm; size: A4; }` control page margins and paper size
  • •`page-break-before: always` / `break-before: page` force a page break before an element
  • •`page-break-inside: avoid` / `break-inside: avoid` prevent breaks inside an element (tables, figures)
  • •`@media print { a::after { content: " (" attr(href) ")"; } }` show link URLs in print
  • •`display: none` on navigation, ads, interactive controls in print styles
  • •Use `<link rel="stylesheet" media="print" href="print.css">` for a separate print stylesheet

Examples

Comprehensive print stylesheet

<style>
/* Screen-only elements: hidden when printing */
@media print {
  nav, .sidebar, .ads, .no-print, footer,
  button, input, select, textarea {
    display: none !important;
  }

  /* Ensure readable typography */
  body {
    font: 12pt Georgia, serif;
    color: #000;
    background: #fff;
  }

  h1 { font-size: 24pt; }
  h2 { font-size: 18pt; }
  h3 { font-size: 14pt; }

  /* Show link URLs after link text */
  a[href]::after {
    content: " (" attr(href) ")";
    font-size: 0.8em;
    color: #666;
  }

  /* Don't show URL for internal or anchor links */
  a[href^="#"]::after,
  a[href^="/"]::after {
    content: "";
  }

  /* Prevent awkward breaks inside these elements */
  figure, table, pre, blockquote, li {
    break-inside: avoid;
  }

  /* Keep headings with their following content */
  h1, h2, h3 {
    break-after: avoid;
  }

  /* Page setup */
  @page {
    margin: 2cm;
    size: A4;
  }
}
</style>

Combine this with semantic HTML the browser uses heading levels and element boundaries for smart page break decisions.

Page breaks and print-specific structure

<!-- Force a new page before each chapter -->
<article class="chapter" style="break-before: page;">
  <h2>Chapter 1: Introduction</h2>
  <p>...</p>
</article>

<article class="chapter" style="break-before: page;">
  <h2>Chapter 2: Getting Started</h2>
  <p>...</p>
</article>

<!-- Prevent a figure from splitting across pages -->
<figure style="break-inside: avoid;">
  <img src="diagram.png" alt="Architecture diagram">
  <figcaption>Figure 1: System Architecture</figcaption>
</figure>

<!-- Print-only elements visible only when printing -->
<div class="print-only">
  <p>Printed on: <span id="print-date"></span></p>
  <p>Source: <span id="print-url"></span></p>
</div>

<style>
  .print-only { display: none; }
  @media print { .print-only { display: block; } }
</style>

<script>
document.getElementById('print-date').textContent = new Date().toLocaleDateString();
document.getElementById('print-url').textContent = window.location.href;
</script>

Triggering print from JavaScript and the beforeprint/afterprint events

<button onclick="window.print()">Print This Page</button>

<script>
// Prepare the page before printing
window.addEventListener('beforeprint', () => {
  console.log('About to print');

  // Expand collapsed sections for print
  document.querySelectorAll('details').forEach(d => {
    d.dataset.wasOpen = d.open;
    d.open = true;
  });

  // Set print date
  document.getElementById('print-date').textContent =
    new Date().toLocaleDateString('en-US', {
      year: 'numeric', month: 'long', day: 'numeric'
    });
});

// Restore state after printing (or cancellation)
window.addEventListener('afterprint', () => {
  console.log('Printing finished or cancelled');

  // Restore collapsed sections
  document.querySelectorAll('details').forEach(d => {
    d.open = d.dataset.wasOpen === 'true';
  });
});
</script>

beforeprint and afterprint fire even when the user cancels the print dialog.

Common Mistakes

  • Using pixel units in print CSS printers use cm, mm, in, pt units; 1pt = 1/72 inch is standard for print
  • Hiding everything with @media print until explicitly un-hiding better to hide specific screen elements so print CSS stays minimal
  • Not testing print output always use Ctrl+P (or browser print preview) during development to verify print layout

Note

Chrome DevTools > Rendering tab has an "Emulate CSS media type" option set it to "print" to see your print CSS applied live in the browser without opening the print dialog.

Exercises

Write HTML to solve each exercise. Use Preview to see it render in a live iframe, then mark as done.

Loading editor…

Completed: 0 / 5 exercises

Knowledge Check

Question 1 of 4

Which CSS at-rule controls the page margins and size when printing?