Convert a Webpage to PDF With Page Breaks Between Sections
Add print-only CSS page breaks so each webpage section starts on a new PDF page, then export and check the result in your browser.
To make each section of a webpage you control start on a new PDF page, add a print stylesheet rule using break-before: page, then open the page’s print dialog and save it as a PDF. For a page you cannot edit, you can still print or save it as a PDF, but the browser cannot reliably add breaks at that site’s semantic section boundaries unless you can change its print styling or use a tool that can apply CSS.
1. Add a page break before each section
Use the page’s actual section selector. This example starts every <section> after the first on a new printed page, without changing the ordinary screen layout:
<style>
@media print {
section {
break-before: page;
}
section:first-of-type {
break-before: auto;
}
}
</style>
<main>
<section>
<h2>Introduction</h2>
<p>Opening content...</p>
</section>
<section>
<h2>Installation</h2>
<p>Installation details...</p>
</section>
<section>
<h2>Configuration</h2>
<p>Configuration details...</p>
</section>
</main>
The first-section override prevents an unnecessary blank opening page. If your sections use a class, target it instead, for example .chapter { break-before: page; }. The rule applies before a generated box; elements that do not generate a box do not get a break.
Use a separate print stylesheet
You can keep the rule in a dedicated file, which makes print-specific behavior easier to maintain:
<link rel="stylesheet" href="print.css" media="print">
/* print.css */
section {
break-before: page;
}
section:first-of-type {
break-before: auto;
}
Alternatively, include the rules inside @media print in your existing stylesheet. Both approaches target printed output, including browser-generated PDFs, rather than the screen view. See the MDN break-before reference and MDN printing guide.
2. Choose the right break property
| Need | CSS | Use |
|---|---|---|
| Start a new page before each section | break-before: page |
Recommended for section starts. |
| Start a new page after each section | break-after: page |
Useful when the break belongs to the end of a block. |
| Keep a short heading with the content that follows | break-after: avoid-page |
Helps prevent a heading from being stranded at the bottom of a page. |
Prefer one deliberate break rule per boundary. Applying both break-after: page to one section and break-before: page to the next can create unexpected blank pages or awkward pagination. The legacy page-break-before property is deprecated; use break-before for new stylesheets. Its legacy always value corresponds to break-before: page.
3. Set page size, orientation, and margins
The @page rule configures the printed page box. For example, this requests portrait A4 pages with 18 mm margins:
@media print {
@page {
size: A4 portrait;
margin: 18mm;
}
section {
break-before: page;
}
section:first-of-type {
break-before: auto;
}
}
Change the page size or orientation to suit the output you need. Available page formats and how browser print settings interact with CSS can vary. Check the target browser’s print preview for the actual page dimensions and margins.
4. Export the page as a PDF
- Save the stylesheet and load the page in the browser where you want to create the PDF.
- Open the browser’s print dialog or print preview.
- Choose the browser’s save-to-PDF destination.
- Check the paper size, orientation, margins, scale, and background graphics options. Some settings may override or affect the CSS page setup.
- Preview every page, then save the PDF and inspect the downloaded file.
For a page you do not control, use the same browser print-to-PDF flow for a basic PDF. You generally cannot insert breaks at the site’s sections with the print dialog alone: those boundaries depend on its markup and print styles. If you need precise section starts on someone else’s page, you need a way to apply print CSS or another conversion workflow that exposes print styling.
5. Handle long sections and awkward content
A forced break starts a section on a fresh page; it does not make the whole section fit on one sheet. Long sections continue onto following pages, where the browser chooses natural break positions. Before exporting, consider these print-specific adjustments:
- Use
break-inside: avoid-pageon small blocks, cards, or figures that should stay together when they fit. Avoid applying it to a very long section or large container, since the browser may have no suitable place to keep it intact. - Use
break-after: avoid-pageon headings when possible, so the heading stays with subsequent content. - Check tables, code blocks, wide images, and long URLs. They may overflow or split poorly at page boundaries; use print-specific width, wrapping, or font-size rules if needed.
- Hide navigation, cookie notices, or other screen-only elements with a print rule such as
.no-print { display: none; }, if those elements should not appear in the PDF. - Do not assume every page uses a semantic
<section>. Inspect the HTML and pick the selector that matches the actual content blocks. A broad selector can also catch nested sections, causing extra breaks.
6. Troubleshoot page-break problems
| Symptom | Likely cause | What to check or change |
|---|---|---|
| No break appears before a section. | The selector does not match, the rule is overridden, or the target has no generated box. | Inspect the element and computed print styles. Confirm the rule is active in print media and targets the section’s actual block element. |
| The PDF starts with a blank page. | The first section also receives a forced break, or another print rule adds a break before the page content. | Reset the first section to break-before: auto and inspect parent and preceding-element break rules. |
| There are blank pages between sections. | Breaks may be applied on both sides of the same boundary, or the page setup and forced breaks interact. | Use one break rule for each boundary and inspect the full print preview, including pages between section starts. |
| A section still spans multiple PDF pages. | A page break starts the section on a new page; it does not constrain its length. | Allow the content to paginate naturally, or redesign the content if it must fit on one page. |
| The printed layout differs from the screen. | Print media rules, browser headers and footers, scaling, paper size, or margins change layout. | Review print-specific computed styles and dialog settings. Test at the intended paper size and scale. |
| Output differs between browsers. | Paginated-media details and browser print behavior can vary. | Test in the actual target browser and version, then inspect its generated PDF. Avoid assuming identical pagination everywhere. |
7. Verify in the target browser
Print CSS is only useful if the target browser honors it as expected. Preview the whole document rather than just the opening page: content length, paper dimensions, and margins all affect natural pagination around the forced section starts. Browser support for paged-media features has varied, so validate the exact browser and version your workflow uses. Chrome for Developers documents that Chrome 131 added support for CSS content in printed-page margins; that version-specific change is separate from the section-break rule itself (Chrome for Developers: CSS in printed page margins).
Or skip the browser setup
For a one-call screenshot or PDF capture, ScreenshotNeo is a website screenshot API and MCP server for developers. Its PDF capture supports paper size, margins, landscape orientation, and page ranges; see the ScreenshotNeo API documentation for request options. A capture API exports the rendered page as a PDF, but CSS page breaks still depend on the page’s print styling.
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://stripe.com \
-d format=pdf \
-o page.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 pdf:
pdf.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 request failed: ${res.status}`);
const pdf = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('page.pdf', pdf));
Cookie and consent banners, newsletter popups, and chat widgets are removed before capture. Bot checks, blank pages, and failed loads are never billed; response headers report the page verdict and billing status. Its MCP server lets AI agents use the take_screenshot, get_page_info, and capture_pdf tools. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Sign up free for 1,000 screenshots a month, with no card required.
FAQ
Does break-before: page force a section to fit on one page?
No. It starts the section on a new page. The content can continue across as many pages as it needs.
Can I add section breaks to a website I do not control?
Only if you can apply print CSS to its content through your workflow. The ordinary print dialog can save a PDF, but it does not reliably identify and break at semantic sections on every site.
Should I use break-before or page-break-before?
Use break-before in new code. page-break-before is the deprecated legacy alias.


