When generating PDFs from HTML, developers frequently encounter a frustrating issue: their carefully crafted @media print CSS rules are completely ignored by wkhtmltopdf. Page breaks do not work, print-specific styling fails to apply, and screen styles appear in the output instead. This issue has persisted throughout wkhtmltopdf's lifetime and, with the project now archived and abandoned, will never receive a fix.
The Problem
wkhtmltopdf, a popular open-source tool for converting HTML to PDF, has a fundamental issue with CSS media query handling. By default, it renders content using the screen media type, meaning any @media print rules in your stylesheets are ignored entirely. While wkhtmltopdf provides a --print-media-type flag to switch to print media emulation, this flag introduces its own set of problems.
The underlying cause traces back to wkhtmltopdf's rendering engine. It uses an ancient version of QtWebKit that corresponds roughly to Chrome 13 from August 2011. This WebKit version has limited and inconsistent support for CSS media queries, particularly those related to print styling.
Error Messages and Symptoms
Developers typically encounter these symptoms:
# PDF generated but all @media print rules ignored
wkhtmltopdf input.html output.pdf
# Using --print-media-type causes opposite problem - non-print styles ignored
wkhtmltopdf --print-media-type input.html output.pdf
Common manifestations include:
-
page-break-before: alwaysandpage-break-after: alwayshave no effect -
@pagerules for margins and size are ignored - Print-specific element hiding (
.no-print { display: none }) fails - Screen-only navigation and UI elements appear in PDF output
- When using
--print-media-type, base styles without media queries are ignored - Images referenced only within
@media printblocks do not render
Who Is Affected
This issue impacts developers across multiple environments:
Operating Systems: Windows, Linux, macOS, and Docker containers
Framework Integrations:
- Ruby on Rails (wicked_pdf, PDFKit)
- Python (pdfkit, django-wkhtmltopdf)
- PHP (Snappy, laravel-dompdf alternatives)
- Node.js (node-wkhtmltopdf, pdf-puppeteer alternatives)
- .NET (various wkhtmltopdf wrappers)
Use Cases:
- Invoice and receipt generation requiring print-specific layouts
- Report generation with page break control
- Document conversion with print stylesheets
- Any HTML-to-PDF workflow using separate print CSS
Scale: The problem affects both single-document generation and high-volume batch processing.
Evidence from the Developer Community
The wkhtmltopdf print media issue has been extensively documented across developer forums and issue trackers over the years.
Timeline
| Date | Event | Source |
|---|---|---|
| 2015-04-27 | Issue reported: print media CSS not affecting PDF | GitHub Issues |
| 2015-04-29 | User reports @media print with page-break-before ignored | GitHub Issues |
| 2022-12-11 | Images not displayed when using --print-media-type | GitHub Issues |
| 2023-01-02 | wkhtmltopdf repository archived, no further fixes | GitHub |
| 2024-12-16 | Homebrew disables wkhtmltopdf cask as discontinued | Homebrew |
Community Reports
"It renders the pdf with styles that are only in the @media print enclosure and ignores the rest of the styles - which DO NOT have @media type specified."
— Stack Overflow user, 2015"My print media css is following. @media print { .new-page { page-break-before: always; } } But when i generate pdf above css not affect on the pdf file."
— GitHub user, Issue #2336"When using @media print styles with the flag --print-media-type, all other CSS loads, but all images do not display in the pdf. If the flag is removed, the images work again."
— GitHub user, Issue #5284"CSS media query orientation:landscape always false even if --orientation landscape is specified."
— GitHub user, Issue #3620
Additional reports confirm that window.matchMedia('print') returns false even when --print-media-type is enabled, that min-width and max-width media queries do not function correctly, and that CSS3 @page size definitions are not supported.
Root Cause Analysis
The print media handling issues in wkhtmltopdf stem from multiple architectural limitations:
Outdated WebKit Engine: wkhtmltopdf uses a patched version of QtWebKit that corresponds to Chrome 13 from 2011. This ancient rendering engine lacks support for many modern CSS features and has incomplete media query implementation.
Media Type Emulation Design: The --print-media-type flag was implemented as a simple media type switch, not a complete print emulation. When enabled, it only evaluates @media print rules and ignores styles without media type specifications, rather than applying both as browsers do during actual printing.
JavaScript Media Query API: The window.matchMedia() API does not correctly reflect the --print-media-type setting, causing JavaScript-based responsive adjustments to fail.
No Active Maintenance: The wkhtmltopdf project was archived on January 2, 2023. The repository is now read-only, meaning these fundamental issues will never be fixed. The project maintainers explicitly stated the tool is no longer maintained and recommended migration to modern alternatives.
Attempted Workarounds
Workaround 1: Duplicate Styles Without Media Query
Approach: Remove the @media print wrapper and include print styles directly.
/* Instead of this */
@media print {
.page-break {
page-break-before: always;
}
.no-print {
display: none;
}
}
/* Use this */
.page-break {
page-break-before: always;
}
.no-print {
display: none;
}
Limitations:
- Breaks browser print preview functionality
- Cannot maintain separate screen and print styles
- Requires maintaining duplicate CSS files or build processes
- Forces print styling on screen display if styles are shared
Workaround 2: Separate CSS Files per Environment
Approach: Create dedicated CSS files and conditionally include them.
<!-- For browser viewing -->
<link rel="stylesheet" href="screen.css" media="screen">
<link rel="stylesheet" href="print.css" media="print">
<!-- For wkhtmltopdf, modify to -->
<link rel="stylesheet" href="print.css" media="all">
Limitations:
- Requires server-side HTML modification before PDF generation
- Complicates build and deployment pipelines
- Cannot use a single HTML source for both display and PDF
- Additional maintenance overhead for duplicate stylesheets
Workaround 3: Inline Critical Print Styles
Approach: Embed print-critical CSS directly in style tags without media queries.
<style>
.force-page-break {
page-break-before: always !important;
break-before: page !important;
}
</style>
Limitations:
- Increases HTML payload size
- Difficult to maintain across multiple templates
- Still does not fix all @page rule issues
- Images within print media blocks may still fail
Workaround 4: Use --print-media-type with Duplicated Base Styles
Approach: Include base styles both without media query and within @media print.
/* Base styles - applied without --print-media-type */
body {
font-family: Arial, sans-serif;
font-size: 12pt;
}
/* Print styles - applied with --print-media-type */
@media print {
body {
font-family: Arial, sans-serif;
font-size: 12pt;
}
.page-break {
page-break-before: always;
}
}
Limitations:
- Massive style duplication
- Easy to introduce inconsistencies
- Does not solve image rendering issues
- Does not fix @page rule limitations
A Different Approach: IronPDF
For developers who need consistent, standards-compliant HTML-to-PDF conversion with proper print media support, IronPDF provides an alternative built on modern browser technology. Unlike wkhtmltopdf's decade-old WebKit, IronPDF uses a current Chromium rendering engine that fully supports CSS media queries, including @media print and @page rules.
Why IronPDF Handles Print Media Correctly
IronPDF renders HTML using an embedded Chromium browser engine. This means:
-
@media printrules are applied correctly by default during PDF rendering -
@pagerules for margins, size, and named pages work as expected -
page-break-before,page-break-after, andpage-break-insidefunction properly - CSS Flexbox, Grid, and modern layout features are fully supported
- JavaScript executes completely before rendering, including media query detection
The rendering pipeline emulates browser print functionality rather than attempting to bolt print support onto a screen renderer.
Code Example
using IronPdf;
// IronPDF respects @media print CSS rules by default
public class PrintMediaExample
{
public void GeneratePdfWithPrintStyles()
{
// Create renderer with print media emulation
var renderer = new ChromePdfRenderer();
// Configure rendering settings
renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print;
// HTML with standard @media print rules - these will be applied
string html = @"
<html>
<head>
<style>
body {
font-family: 'Segoe UI', Arial, sans-serif;
}
.header {
background: #333;
color: white;
padding: 20px;
}
@media print {
.header {
background: none;
color: black;
border-bottom: 2px solid #333;
}
.no-print {
display: none !important;
}
.page-break {
page-break-before: always;
}
}
@page {
size: A4;
margin: 2cm;
}
@page :first {
margin-top: 3cm;
}
</style>
</head>
<body>
<nav class='no-print'>Navigation - hidden in PDF</nav>
<div class='header'>
<h1>Invoice #12345</h1>
</div>
<div class='content'>
<p>Invoice content here...</p>
</div>
<div class='page-break'></div>
<div class='content'>
<p>Second page content...</p>
</div>
</body>
</html>";
// Generate PDF - @media print rules are automatically applied
var pdf = renderer.RenderHtmlAsPdf(html);
pdf.SaveAs("invoice-with-print-styles.pdf");
}
}
Key points about this code:
-
CssMediaType.Printensures print media styles are applied, though IronPDF handles print context by default - Standard
@media printCSS works without modification -
@pagerules for size and margins are respected -
page-break-beforeand related properties function correctly - No workarounds or style duplication required
API Reference
For more details on the methods used:
Migration Considerations
Licensing
IronPDF is commercial software with perpetual licensing options. A free trial is available for evaluation, and licensing includes one year of updates and support. For pricing details, see the IronPDF licensing page.
API Differences
Migration from wkhtmltopdf command-line usage to IronPDF requires code changes:
| wkhtmltopdf | IronPDF |
|---|---|
--print-media-type |
RenderingOptions.CssMediaType = Print |
--page-size A4 |
RenderingOptions.PaperSize = A4 |
--margin-top 10mm |
RenderingOptions.MarginTop = 10 |
--orientation Landscape |
RenderingOptions.PaperOrientation = Landscape |
| Command-line execution | .NET library calls |
For developers using wkhtmltopdf wrappers in Python, Ruby, or PHP, equivalent IronPDF libraries exist for those platforms as well.
What You Gain
- Print media query support that matches browser behavior
- Modern CSS support including Flexbox, Grid, and CSS3
- Active development and security updates
- JavaScript execution with configurable delays
- Commercial support and documentation
What to Consider
- Requires .NET runtime (or alternative language SDKs)
- Commercial license required for production use
- Different API than command-line wkhtmltopdf
- Chromium-based rendering may have different text rendering characteristics
Conclusion
The wkhtmltopdf print media issue is a fundamental limitation of an abandoned tool built on obsolete technology. With the project archived and no fixes forthcoming, developers have two choices: implement complex workarounds that may not fully resolve the issue, or migrate to a maintained solution with proper print media support. IronPDF offers standards-compliant HTML-to-PDF conversion using modern Chromium rendering, where @media print rules work as intended without workarounds.
Jacob Mellor is CTO at Iron Software with 25+ years of commercial software experience, including building IronPDF.
References
- wkhtmltopdf print-media-type uses @media print ONLY and ignores the rest{:rel="nofollow"} - Stack Overflow discussion of media type handling issue
- print-media-type Issue #2336{:rel="nofollow"} - GitHub issue for page-break CSS not working
- --print-media-type all images not displayed Issue #5284{:rel="nofollow"} - Image rendering failure with print media flag
- @page and @media supported? Issue #2485{:rel="nofollow"} - Discussion of media query support limitations
- Not matching print media query Issue #2861{:rel="nofollow"} - JavaScript media query mismatch
- CSS media issue print vs screen Issue #2327{:rel="nofollow"} - Version differences in CSS media handling
- page-breaks ignored Issue #1551{:rel="nofollow"} - Page break CSS being ignored
- wkhtmltopdf Status Page{:rel="nofollow"} - Official project status and discontinuation notice
- CIVI-PSA-2024-01: wkhtmltopdf EOL Advisory{:rel="nofollow"} - Security advisory regarding wkhtmltopdf end of life
- wkhtmltopdf CSS Support Fix Guide{:rel="nofollow"} - Third-party documentation of CSS issues and workarounds
For the latest IronPDF documentation and tutorials, visit ironpdf.com.
Top comments (0)