CSS Tips for Perfect PDF Output
The screen and the printed page are fundamentally different mediums. This comprehensive guide covers everything you need to know about styling HTML for flawless PDF conversion—from basic print stylesheets to advanced page break control and troubleshooting.
Understanding Print Media Queries
The foundation of PDF-ready CSS is the @media print query. This special media type targets styles that only apply when the document is printed or converted to PDF. Everything inside this block is ignored on screen.
Think of it as having two completely separate stylesheets: one for screens and one for paper. This separation allows you to hide navigation, adjust typography, and optimize layouts specifically for the printed medium.
@media print {
/* Hide screen-only elements */
nav,
.sidebar,
.no-print,
button,
.cookie-banner {
display: none !important;
}
/* Reset backgrounds and colors */
body {
background: white !important;
color: black !important;
font-size: 12pt;
line-height: 1.6;
}
/* Ensure proper page margins */
@page {
margin: 2cm;
size: A4 portrait;
}
}The @page Rule
The @page rule controls the physical page properties. You can set paper size, margins, and even target specific pages like the first page or left/right pages in a book layout.
Common Page Sizes
size: A4;— 210mm × 297mm (standard in Europe)size: letter;— 8.5in × 11in (standard in US)size: legal;— 8.5in × 14insize: A4 landscape;— horizontal orientationsize: 100mm 200mm;— custom dimensions
Mastering Page Breaks
Page break control is perhaps the most important aspect of PDF styling. Nothing ruins a document faster than a heading orphaned at the bottom of a page or a table split awkwardly across two pages.
CSS provides three properties for page break control, each with modern and legacy syntax:
- page-break-before / break-before: Controls whether a page break occurs before an element
- page-break-after / break-after: Controls page breaks after an element
- page-break-inside / break-inside: Controls whether an element can be split across pages
/* Force page break before element */
.chapter-start,
.new-section {
page-break-before: always;
break-before: page; /* Modern syntax */
}
/* Force page break after element */
.end-of-section {
page-break-after: always;
break-after: page;
}
/* Prevent element from being split */
.keep-together,
table,
figure,
blockquote,
.testimonial {
page-break-inside: avoid;
break-inside: avoid;
}
/* Keep headings with following content */
h1, h2, h3, h4, h5, h6 {
page-break-after: avoid;
break-after: avoid;
}
/* Orphan and widow control */
p {
orphans: 3; /* Min lines at bottom of page */
widows: 3; /* Min lines at top of page */
}Orphans and Widows
In typography, an "orphan" is a single line of a paragraph left alone at the bottom of a page, while a "widow" is a single line at the top of a page. Both are considered poor typography. The orphans and widows properties set the minimum number of lines that must appear together.
Browser Compatibility Note
Use both the legacy (page-break-*) and modern (break-*) syntax for maximum compatibility. Chrome, Safari, and html2pdf.js work best with the legacy syntax, while Firefox prefers the modern version.
Backgrounds and Colors
By default, browsers do not print background colors and images. This is a deliberate choice to save ink. However, for documents where backgrounds are essential (like invoices with branded headers), you need to explicitly enable them.
@media print {
/* Force background colors to print */
* {
-webkit-print-color-adjust: exact !important;
print-color-adjust: exact !important;
color-adjust: exact !important;
}
/* Alternative: Use borders instead of backgrounds */
.highlight-box {
/* Instead of: background: #fef3c7; */
border: 2px solid #f59e0b;
padding: 1rem;
}
/* Header with guaranteed visibility */
.header {
background: #1e293b !important;
color: white !important;
-webkit-print-color-adjust: exact !important;
}
}When Backgrounds Won't Print
Even with print-color-adjust: exact, users can override this in their browser's print settings. For mission-critical elements, consider alternatives:
- Use borders instead of background colors for highlighting
- Use inline SVG for colored shapes that must appear
- Consider dark text on white backgrounds as the default
Typography and Web Fonts
Font rendering in PDFs can be tricky. Web fonts loaded from Google Fonts or Adobe Fonts must be fully downloaded before the PDF is generated, or you'll see fallback fonts.
/* Define print-safe font stack */
body {
font-family:
'Segoe UI', /* Windows */
'SF Pro Text', /* macOS */
'Roboto', /* Android/Chrome OS */
-apple-system, /* Safari fallback */
Arial, /* Universal fallback */
sans-serif;
}
/* Ensure web fonts are loaded before print */
@font-face {
font-family: 'CustomFont';
src: url('/fonts/custom.woff2') format('woff2');
font-display: block; /* Wait for font to load */
}
/* Print-specific typography */
@media print {
body {
font-size: 12pt;
line-height: 1.5;
}
h1 { font-size: 24pt; }
h2 { font-size: 18pt; }
h3 { font-size: 14pt; }
/* Avoid thin fonts that don't print well */
* {
font-weight: normal;
}
strong, b, h1, h2, h3 {
font-weight: bold;
}
}Font Size in Print
On screen, we typically use pixels or relative units (rem, em). For print, points (pt) are the traditional unit. The standard conversion is 1pt = 1/72 inch. Common sizes:
- Body text: 10pt - 12pt
- Headings: 14pt - 24pt
- Captions and footnotes: 8pt - 9pt
Safe System Fonts
These fonts are available on virtually all systems and don't require loading:
- • Sans-serif: Arial, Helvetica, Verdana, Trebuchet MS
- • Serif: Times New Roman, Georgia, Palatino
- • Monospace: Courier New, Consolas, Monaco
Layout Strategies
Modern CSS layouts with Flexbox and Grid work well for PDF generation, but you may need adjustments for the fixed dimensions of paper. A4 paper is 210mm × 297mm, and with typical 2cm margins, your content area is approximately 170mm × 257mm.
/* A4-optimized container */
.print-container {
max-width: 210mm;
padding: 20mm;
margin: 0 auto;
box-sizing: border-box;
}
/* Content width for comfortable reading */
.content {
max-width: 170mm; /* 210mm - 40mm margins */
}
@media print {
/* Remove max-width constraints */
.print-container,
.content {
max-width: none;
width: 100%;
padding: 0;
margin: 0;
}
/* Convert flex/grid to simpler layouts if needed */
.complex-grid {
display: block;
}
.complex-grid > * {
width: 100%;
margin-bottom: 1rem;
}
}Dealing with Sidebars
Two-column layouts that work on screen often don't translate well to print. Consider:
- Hiding sidebars entirely for print
- Moving sidebar content to the end of the document
- Converting to a single-column layout
Images and Media
Images require special attention for PDF output. Lazy-loaded images may not be loaded when the PDF is generated, and high-resolution images can make PDFs enormous.
/* Ensure images don't overflow pages */
img {
max-width: 100%;
height: auto;
page-break-inside: avoid;
}
/* Handle lazy-loaded images */
img[loading="lazy"] {
loading: eager; /* Force immediate load for print */
}
@media print {
/* Ensure images print */
img {
display: block !important;
visibility: visible !important;
max-width: 100% !important;
/* Prevent quality loss */
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
}
/* Hide decorative images */
.decorative-bg,
.parallax-image {
display: none !important;
}
/* Ensure alt text shows if image fails */
img::after {
content: attr(alt);
font-style: italic;
color: #666;
}
}Image Resolution
For print-quality output, images should be at least 300 DPI (dots per inch). On screen, we typically see 72-96 DPI. If your PDF will be printed, ensure images are high enough resolution, or they'll appear pixelated.
For web-to-PDF conversion where printing isn't the goal, standard screen resolution is fine. The html2pdf.js scale option effectively increases rendering resolution.
Handling Links
On screen, links are obvious—they're blue and clickable. On paper, you need to make URLs visible so readers can type them manually. CSS can automatically append URLs after link text.
@media print {
/* Make links visible but not distracting */
a {
color: #000 !important;
text-decoration: underline;
}
/* Show URL after external links */
a[href^="http"]:after,
a[href^="https"]:after {
content: " (" attr(href) ")";
font-size: 0.8em;
color: #666;
word-break: break-all;
}
/* Don't show URL for internal links */
a[href^="#"]:after,
a[href^="/"]:after {
content: none;
}
/* Don't show URL for email links */
a[href^="mailto"]:after {
content: " (" attr(href) ")";
}
/* Limit very long URLs */
a:after {
max-width: 200px;
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
vertical-align: bottom;
}
}Tables for Print
Tables present unique challenges for PDF generation. Long tables spanning multiple pages need repeating headers, and complex layouts may need simplification.
/* Print-optimized tables */
table {
width: 100%;
border-collapse: collapse;
page-break-inside: auto;
}
tr {
page-break-inside: avoid;
page-break-after: auto;
}
thead {
display: table-header-group; /* Repeat header on each page */
}
tfoot {
display: table-footer-group;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
@media print {
th {
background: #f3f4f6 !important;
-webkit-print-color-adjust: exact;
}
/* Zebra striping */
tr:nth-child(even) {
background: #f9fafb !important;
-webkit-print-color-adjust: exact;
}
/* Ensure table fits page width */
table {
font-size: 10pt;
}
}Table Header Repetition
The display: table-header-group property on thead tells the browser to repeat the header row on each page. This is essential for data tables that span multiple pages.
Complete Print Stylesheet Template
Here's a comprehensive print stylesheet you can use as a starting point for any project. It incorporates all the techniques discussed above.
/* Complete Print Stylesheet Template */
@media print {
/* ===== RESET & BASICS ===== */
* {
-webkit-print-color-adjust: exact !important;
print-color-adjust: exact !important;
}
body {
background: white !important;
color: black !important;
font-family: 'Segoe UI', Arial, sans-serif;
font-size: 12pt;
line-height: 1.6;
}
/* ===== PAGE SETUP ===== */
@page {
size: A4 portrait;
margin: 2cm;
}
@page :first {
margin-top: 1cm; /* Smaller top margin for first page */
}
/* ===== HIDE ELEMENTS ===== */
nav, footer, aside,
.no-print, .sidebar,
button, .modal,
.cookie-banner,
.social-share,
.comments-section {
display: none !important;
}
/* ===== PAGE BREAKS ===== */
h1, h2, h3 {
page-break-after: avoid;
}
h1 {
page-break-before: always;
}
h1:first-of-type {
page-break-before: avoid;
}
table, figure, img, blockquote {
page-break-inside: avoid;
}
p {
orphans: 3;
widows: 3;
}
/* ===== TYPOGRAPHY ===== */
h1 { font-size: 24pt; margin-bottom: 12pt; }
h2 { font-size: 18pt; margin-top: 18pt; }
h3 { font-size: 14pt; }
/* ===== LINKS ===== */
a {
color: black !important;
text-decoration: underline;
}
a[href^="http"]:after {
content: " [" attr(href) "]";
font-size: 0.8em;
color: #666;
}
/* ===== IMAGES ===== */
img {
max-width: 100% !important;
page-break-inside: avoid;
}
/* ===== TABLES ===== */
table {
width: 100%;
border-collapse: collapse;
font-size: 10pt;
}
th, td {
border: 1px solid #ccc;
padding: 6pt;
}
thead {
display: table-header-group;
}
th {
background: #f0f0f0 !important;
}
}Troubleshooting Common Issues
Problem: Content is cut off
Solution: Check that your container doesn't have a fixed height. Use min-height instead of height. Ensure overflowis set to visible, not hidden.
Problem: Backgrounds disappear
Solution: Add -webkit-print-color-adjust: exact andprint-color-adjust: exact to the elements. Remember that users can still override this in browser settings.
Problem: Fonts look different
Solution: Ensure web fonts are fully loaded before generating the PDF. Use document.fonts.ready in JavaScript. Provide fallback fonts that closely match your web fonts.
Problem: Page breaks in wrong places
Solution: Use both legacy and modern syntax for page-break properties. Add break-inside: avoid to elements that shouldn't be split. Check that parent elements don't have conflicting break properties.
Conclusion
Creating CSS for PDF output requires a different mindset than screen design. The key principles to remember:
- Use
@media printto create separate print styles - Control page breaks explicitly with CSS properties
- Force background printing when needed with
print-color-adjust - Use points (pt) for font sizes in print
- Ensure images and fonts are loaded before PDF generation
- Hide interactive elements that don't make sense on paper
With these techniques, you can create documents that look professional whether viewed on screen or converted to PDF.
Test Your CSS
Try our free HTML to PDF converter to see your print styles in action.
Convert HTML to PDF