The document is wrong
The PDF renders the mobile layout instead of the desktop one
Your responsive document collapses to a single narrow column, the sidebar drops below the content, and the type looks oversized for the page.
What is actually happening
The render viewport is narrower than your first breakpoint, so your own media queries are doing exactly what you told them to. A4 at 96 dots per inch is 794 pixels wide, which is below the 768 or 1024 pixel breakpoint most designs treat as the boundary between phone and desktop.
Confirming it is this and not something that looks like it
Resize a browser window to 794 pixels wide and look at the page. If it matches the PDF, your breakpoints are the cause.
The fix
Write the document's CSS for the page rather than reusing the screen CSS. A printed document does not have breakpoints; it has one width, which you know in advance. Put the document styles in their own stylesheet with no media queries at all, rather than trying to find a viewport that makes the screen styles behave.
/* Document CSS is not responsive CSS. There is exactly one width. */
@page {
size: A4;
margin: 18mm 16mm;
}
.document {
/* The content box of an A4 page at the margins above. */
width: 178mm;
font-size: 10.5pt;
line-height: 1.45;
}
/* No breakpoints below this line. If you find yourself writing one, the
document is being asked to be two documents. */If that was not it
These produce the same symptom often enough to be worth ruling out before assuming the fix above did not work.
- A viewport meta tag with initial-scale, which affects the browser and not the paged render
- Container queries, which behave the same way and for the same reason
- Utility classes from a framework whose default breakpoints you did not choose
Frequently asked
Does this happen with every rendering engine?
The behaviour behind it is not specific to one tool. The render viewport is narrower than your first breakpoint, so your own media queries are doing exactly what you told them to. Anything rendering HTML to a paged medium has to make the same decision, so the fix travels with you if you change how the render happens.
Will this show up as an error in my logs?
No, and that is what makes it expensive. A document that renders wrong is still a successful render as far as every log line is concerned. It is found by someone opening the file, which is usually the customer.
Related failures
Problems people arrive at from the same starting point, or mistake for this one.
Background colours and images are missing from the PDF
Browsers drop backgrounds when printing, because a page with every background painted would empty a toner cartridge, and most render APIs inherit that default.
The generated PDF is blank
Almost always one of three things: the content is rendered by JavaScript that had not run when the snapshot was taken, the body has no height because everything inside it is absolutely positioned or floated, or the markup you sent was empty because the template call returned before the data arrived..
Images do not appear in the PDF
The image src is a path rather than a URL.
The PDF ignores my CSS
The stylesheet is linked rather than embedded, and the link points somewhere the renderer cannot reach: a bundler-generated path, a digested asset filename, or a URL behind your application's authentication.
Content rendered by JavaScript is missing from the PDF
The snapshot was taken before the script finished.
CSS for paged documents, and what actually works
Which parts of the paged media specification a browser-based render implements.
Everything that goes wrong, by category
The full list, grouped by where in the pipeline it breaks.
Paste your markup and see the rendered document, without signing up.