Responsive CSS designed for screens often breaks in PDFs — multi-column layouts collapse, navigation menus disappear, mobile breakpoints activate incorrectly. I've debugged invoice systems where PDFs rendered in single-column mobile layouts despite targeting A4 paper, reports where CSS Grid layouts collapsed into vertical stacks, and documentation where @media print stylesheets were ignored entirely.
The root cause: PDF rendering uses different CSS media types than browsers. Browsers default to screen media type (optimized for displays). Print operations use print media type (optimized for paper). Many developers write CSS assuming screen rendering, then wonder why PDFs look wrong — the rendering engine applies different CSS rules for print media.
Understanding CSS media types solves most PDF layout issues. Modern CSS supports @media screen (digital displays) and @media print (printers, PDF). Define screen styles for web viewing, print styles for PDF output. IronPDF lets you choose which media type to apply during rendering — PdfCssMediaType.Screen (default) or PdfCssMediaType.Print.
The practical implication: if your HTML looks correct in a browser but breaks in PDF, you're likely hitting media type mismatches. Test HTML with browser print preview (Ctrl+P / Cmd+P) — if print preview looks broken, PDF will too. Fix CSS for print media type, PDFs render correctly.
using IronPdf;
// Install via NuGet: Install-Package IronPdf
var renderer = new ChromePdfRenderer();
// Use print CSS media type for PDF-optimized rendering
renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print;
var html = @"
<!DOCTYPE html>
<html>
<head>
<style>
@media screen {
body { background-color: #f3f4f6; }
nav { display: block; }
}
@media print {
body { background-color: white; }
nav { display: none; }
table thead { display: table-header-group; }
}
</style>
</head>
<body>
<nav>Website Navigation</nav>
<table>
<thead>
<tr><th>Column</th></tr>
</thead>
<tbody>
<tr><td>Data</td></tr>
</tbody>
</table>
</body>
</html>
";
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("report.pdf");
With CssMediaType = Print, the navigation hides (nav { display: none; }), background becomes white (print-optimized), and table headers repeat on each page (thead { display: table-header-group; }). These are print-specific optimizations browsers apply automatically during printing.
What NuGet Packages Do I Need?
Install IronPDF via Package Manager Console:
Install-Package IronPdf
Or .NET CLI:
dotnet add package IronPdf
IronPDF includes CSS media type handling in the core library.
Why Do Table Headers Need Special Handling?
Multi-page tables in PDFs should repeat headers at the top of each page — like printed spreadsheets. This requires @media print CSS and semantic HTML:
var html = @"
<style>
@media print {
table thead { display: table-header-group; }
table tfoot { display: table-footer-group; }
}
</style>
<table>
<thead>
<tr>
<th>Product</th>
<th>Price</th>
</tr>
</thead>
<tbody>
<!-- 100 rows... -->
</tbody>
<tfoot>
<tr>
<td>Total:</td>
<td>$12,345</td>
</tr>
</tfoot>
</table>
";
var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.CssMediaType = PdfCssMediaType.Print;
var pdf = renderer.RenderHtmlAsPdf(html);
Without CssMediaType.Print, headers don't repeat. With it enabled, <thead> rows repeat at the top of every PDF page containing table content. <tfoot> rows repeat at the bottom.
I generate financial reports this way — 50-page tables with headers showing column labels on every page. Users can print any page individually and still see what each column represents.
What's the Difference Between Screen and Print Media Types?
Screen Media Type (PdfCssMediaType.Screen, default):
- Preserves navigation, sidebars, interactive elements
- Uses screen-optimized colors (often darker backgrounds)
- Respects responsive breakpoints as if viewing on desktop
- Preserves animations, hover effects (static in PDF but CSS loads)
- Suitable for web page archival, "Save as PDF" functionality
Print Media Type (PdfCssMediaType.Print):
- Hides navigation, sidebars, footers (content-focused)
- Uses print-optimized colors (white backgrounds, dark text for readability)
- Applies print-specific layouts (multi-column for newspaper style)
- Enables repeating table headers/footers
- Suitable for reports, invoices, printable documents
Choose based on use case: archiving web pages as-displayed → Screen. Generating reports for printing → Print.
How Do I Write CSS for Both Screen and Print?
Use @media queries to define separate styles:
/* Base styles (apply to both) */
body {
font-family: Arial, sans-serif;
font-size: 12pt;
}
/* Screen-only styles */
@media screen {
body {
background-color: #1a1a1a;
color: #ffffff;
}
.sidebar {
display: block;
}
.page-break {
display: none;
}
}
/* Print-only styles */
@media print {
body {
background-color: white;
color: black;
}
.sidebar {
display: none;
}
.page-break {
page-break-after: always;
}
a[href]:after {
content: " (" attr(href) ")";
}
}
This CSS adapts: dark mode for screens, white for print. Sidebars visible on screen, hidden in print. Page breaks ignored on screen, enforced in print. Links show URLs when printed.
I use this pattern for documentation systems — users read docs online (screen media), print specific sections (print media optimized with page breaks, no navigation clutter).
How Do I Handle Responsive Breakpoints in PDFs?
Responsive CSS uses viewport width to adapt layouts (@media (max-width: 768px)). PDFs have fixed page widths (A4 is 210mm ~= 595px at 72 DPI). If your mobile breakpoint is 768px, A4 pages may trigger it unexpectedly.
Set viewport width explicitly to avoid mobile layouts:
renderer.RenderingOptions.ViewPortWidth = 1024; // Desktop viewport
This forces the renderer to treat content as if viewed on a 1024px wide screen, applying desktop CSS even though PDF page is narrower.
For completely custom PDF layouts, use print media type with dedicated print stylesheets:
@media print {
.container {
width: 100%;
max-width: none;
}
.mobile-menu {
display: none !important;
}
}
What About Modern CSS Features (Grid, Flexbox)?
Chromium-based rendering supports CSS Grid, Flexbox, custom properties (CSS variables), modern selectors. If CSS works in Chrome browser, IronPDF renders it identically.
@media print {
.report-layout {
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 20px;
}
}
This creates two-column print layouts using CSS Grid — fully supported.
Bootstrap, Tailwind CSS, Foundation all work as long as stylesheets are accessible (embedded, or via BaseUrlOrPath for external CSS files).
How Does IronPDF Compare to wkhtmltopdf for Print CSS?
wkhtmltopdf uses WebKit from 2016 — before many modern CSS features stabilized. Its print media support is buggy:
- Table headers don't repeat reliably
- CSS Grid partially broken
- Custom properties (CSS variables) unsupported
- Some
@media printrules ignored
IronPDF uses Chromium, matching current Chrome browser capabilities:
- Full
@media printsupport - Reliable table header repetition with
<thead> - Complete CSS Grid and Flexbox
- Custom properties, modern selectors, everything
I migrated a reporting system from wkhtmltopdf specifically because table headers failed to repeat on multi-page reports. Switching to IronPDF with CssMediaType.Print fixed it immediately — headers repeated correctly on all pages.
What Common Issues Should I Watch For?
Page break forcing: Use page-break-after: always or page-break-before: always in print CSS to control pagination:
@media print {
.section {
page-break-after: always;
}
}
Avoid breaking inside elements: Use page-break-inside: avoid to prevent page breaks within tables, images, or sections:
@media print {
table {
page-break-inside: avoid;
}
}
Testing print layouts: Always test HTML with browser print preview (Ctrl+P / Cmd+P) before generating PDFs. If print preview looks broken, PDF will too.
Default media type: IronPDF defaults to Screen. Remember to explicitly set CssMediaType.Print for reports requiring print-optimized layouts.
I've debugged issues where developers assumed Print was default, generated PDFs with screen-optimized CSS (navigation, sidebars, dark backgrounds), and wondered why PDFs looked unprofessional. Explicitly setting media type prevents assumptions.
Quick Reference
| CSS Feature | Screen Media | Print Media | Use Case |
|---|---|---|---|
| Navigation/Sidebars | Visible | Hidden | Content focus in print |
| Background colors | Any color | White/light | Print ink savings |
| Table headers | Normal | Repeat on pages | Multi-page tables |
| Page breaks | Ignored | Enforced | Section separation |
| Links | Clickable | Show URLs | Print reference |
| Responsive breakpoints | Active | Often disabled | Fixed page sizes |
| Multi-column | Flex/Grid | Print columns | Newspaper layouts |
Key Principles:
-
CssMediaType.Screen(default) preserves web appearance,CssMediaType.Printoptimizes for printing - Use
@media printCSS for print-specific styles (hide navigation, white backgrounds, page breaks) - Table headers repeat only with
CssMediaType.Print+<thead>tags +display: table-header-group - Test HTML with browser print preview before generating PDFs
- IronPDF's Chromium engine fully supports modern CSS (Grid, Flexbox, variables)
- wkhtmltopdf has broken print media support — avoid for new projects
- Set
ViewPortWidthto control responsive breakpoints in fixed-width PDFs - Use
page-break-after,page-break-before,page-break-insidefor pagination control
The complete responsive CSS guide includes examples for complex layouts and print optimization patterns.
*Written by Jacob Mellor, CTO at Iron Software. Jacob created IronPDF and leads a team of 50+ engineers building .NET document processing libraries.
Top comments (0)