Convert a Webpage to PDF with CSS Print Styles in Chrome
Build a cleaner PDF with print-specific CSS, set page size and margins, preview the result in Chrome, then save it as a PDF.
To convert a webpage to PDF with CSS print styles in Chrome, define print-only rules with @media print, set page dimensions and margins with @page, inspect the print rendition, then open Chrome’s print interface and choose its PDF destination. These styles affect printed output, including PDF output; they do not change the page’s on-screen presentation.
1. Add print-specific CSS
For a small number of rules, add an @media print block to your existing stylesheet. Replace the example selectors with selectors from your page.
@media print {
/* Remove elements that are useful on screen but not in the document. */
.site-navigation,
.cookie-banner,
.share-controls,
.print-button {
display: none !important;
}
/* Allow the main content to use the printable width. */
main {
max-width: none;
margin: 0;
}
/* Keep links readable without relying on screen colors. */
a {
color: inherit;
text-decoration: underline;
}
/* Avoid splitting short content blocks when possible. */
figure,
blockquote,
pre {
break-inside: avoid;
}
/* Do not print decorative shadows or backgrounds. */
* {
box-shadow: none !important;
text-shadow: none !important;
}
}
A separate stylesheet can keep a larger print design isolated. Put this in the document’s <head>:
<link rel="stylesheet" href="print.css" media="print">
Either approach is valid. CSS specificity and cascade rules still apply in print media: a more specific competing declaration can override a rule in your print block. Inspect computed styles if a rule appears to have no effect. See MDN’s printing guide.
2. Choose page size, orientation, and margins
Use @page to set the paper size, orientation, and page margins. For example, this chooses portrait A4 and leaves 16 millimeters around the page content:
@page {
size: A4 portrait;
margin: 16mm;
}
For landscape output, use size: A4 landscape;. You can also specify a margin shorthand such as margin: 12mm 16mm; for different vertical and horizontal margins. Browser support for less common paged-media features varies, so use the basic size and margin settings for a general Chrome workflow and verify advanced behavior in the Chrome version you target. See MDN’s @page reference.
3. Preview print media in Chrome
Before saving, inspect the page as Chrome will print it. Open DevTools, open the Rendering panel, and set “Emulate CSS media type” to print. The page then uses print styles while you inspect it, and you can edit CSS in DevTools to refine spacing, visibility, and layout. This preview is useful for style checks; use the actual print interface as well to inspect pagination and print settings. See Chrome DevTools Rendering tools.
4. Save the page as a PDF
- Open Chrome’s print interface from the browser UI or call
window.print()from the page. - Review the page previews, paper size, orientation, margins, and any header/footer setting.
- Select the PDF destination offered by Chrome and save the file.
Exact menu wording can vary by operating system and Chrome version. A page can provide a print button like this:
<button type="button" onclick="window.print()">Print or save as PDF</button>
window.print() opens the print dialog for the current document. If the document is still loading, the browser completes loading before opening the dialog. See MDN’s Window.print() reference.
Controlling page breaks and long content
Print layout fragments content across page boxes. You can suggest where breaks should happen and discourage breaks inside a component:
@media print {
.chapter {
break-before: page;
}
h2,
figure,
.summary-card {
break-inside: avoid;
}
.end-of-section {
break-after: page;
}
}
Break avoidance is a hint, not a guarantee: an element taller than the printable page must still split or overflow. Avoid applying break-inside: avoid indiscriminately to large containers, because it can create awkward whitespace or force a large block onto another page.
Headers, footers, and page-margin content
Chrome can add browser-generated headers and footers, such as page information, when the print settings enable them and enough margin space is available. Turn them off in the print interface if the document should have clean edges or its own page furniture. Very small or zero page margins leave no room for the browser-generated content.
For CSS-generated content in page-margin boxes, Chrome for Developers documents support beginning in Chrome 131. This is distinct from ordinary @media print and @page styling. Margin-box behavior and other advanced paged-media features can vary; check the target Chrome build and preview the result. Browser-generated headers and footers may coexist with author-provided margin content. See Chrome for Developers’ article on adding content to printed page margins.
Common problems and fixes
| Problem | Likely cause | Fix |
|---|---|---|
| A print rule does not take effect | A more specific selector or another declaration wins in the cascade. | Inspect the computed style in print emulation, increase selector specificity only as needed, or remove the competing rule. |
| Navigation or a banner still appears | The selector does not match the actual element, or the element is recreated by page code. | Check the element in DevTools and target its actual selector. Confirm the print stylesheet loads and that its media is print. |
| Content is clipped or too wide | Fixed widths, large margins, or screen-only layout constraints remain active. | Remove fixed maximum widths and horizontal margins in print CSS; inspect the selected paper size and orientation. |
| A heading or image is stranded at a page edge | Natural pagination split a related group. | Apply break-inside: avoid to a suitably sized group, or use break-before for a section where a new page is appropriate. |
| Unexpected URL/date headers appear | Chrome’s print header/footer option is enabled. | Disable headers and footers in the print interface or reserve and design the page margins intentionally. |
| CSS margin content is missing | The Chrome version may not support the feature, or the page-margin syntax and available space are unsuitable. | Use Chrome 131 or later for the documented generated margin content feature, check the syntax against Chrome’s guidance, and preview. Basic print rules do not require Chrome 131. |
| The print button opens a dialog before the page looks ready | Application content or images load after the document’s load event. | Wait for the page’s own content-ready condition before invoking window.print(); verify the final rendering in the print preview. |
Performance, reliability, and output quality
- Keep the print stylesheet focused. Hiding large screen-only sections and removing expensive decorative effects can simplify the print rendition, though the main cost is usually the page’s own loading and layout work.
- Wait for dynamic content. A print dialog can open after the document finishes loading, but client-rendered content, delayed images, or application data may have separate readiness timing. Trigger printing only when the content you need is present.
- Check page breaks at the final paper size. Changing paper size, orientation, margins, browser settings, or content can change pagination. Preview after meaningful stylesheet or content changes.
- Do not assume color backgrounds print. Print settings and browser behavior can affect background colors. Make text and boundaries understandable without decorative color alone.
- Expect browser differences for advanced features. The basic print workflow is broadly supported, while paged-media details can differ. Validate the target Chrome version when relying on advanced page rules.
Or skip the browser setup
If you need a screenshot image or PDF through an API, ScreenshotNeo is a website screenshot API and MCP server. Its API can return a screenshot or PDF from one GET request. For this webpage-to-PDF workflow, the request below demonstrates the API call; see the ScreenshotNeo documentation for its parameters and options.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.pdf
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com", "format": "pdf"},
timeout=90,
)
r.raise_for_status()
with open("page.pdf", "wb") as f:
f.write(r.content)
const q = new URLSearchParams({
access_key: 'YOUR_API_KEY',
url: 'https://stripe.com',
format: 'pdf'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`ScreenshotNeo returned ${res.status}`);
const bytes = new Uint8Array(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('page.pdf', bytes));
ScreenshotNeo removes cookie and consent banners, newsletter popups, and chat widgets before capture; each of these cleanup steps can be turned off. Bot checks, blank pages, and failed loads are not billed, and response headers report the page verdict and billing status. Its MCP server lets AI agents take screenshots. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Sign up for 1,000 free screenshots a month, with no card required.
FAQ
Does print CSS change the webpage for visitors?
No. Rules inside @media print apply to print output, including a PDF, while screen presentation remains governed by screen styles.
Can I make the PDF landscape?
Yes. Set size: A4 landscape; in @page, then confirm the resulting layout in Chrome’s print preview.
Do I need JavaScript to save a page as PDF?
No. You can open Chrome’s print interface directly. JavaScript’s window.print() is useful when providing a print button on the page.
Do I need Chrome 131 for print styles?
No. Chrome 131 is relevant to CSS-generated content in page-margin boxes. The ordinary print stylesheet and basic page size and margin workflow are separate features.


