Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Style the source <div> with ordinary HTML and CSS, then pass its containing element to html2pdf.js. The library does not provide a separate styling language: it clones the DOM, renders it through html2canvas, and writes the result with jsPDF. Your CSS controls the visual design; html2pdf.js controls export settings and pagination.

For predictable PDFs, give the exported root an explicit width, box model, colors, spacing and typography, then add CSS break rules or pagebreak selectors for page boundaries. Always inspect the generated PDF, because the cloned export DOM can differ from the live page.

How html2pdf.js turns a styled div into a PDF

The normal pipeline is entirely client-side:

  1. Your browser builds the HTML and applies CSS.
  2. html2pdf.js clones the element you pass to .from().
  3. html2canvas paints that clone onto a canvas.
  4. jsPDF places the rendered result on one or more PDF pages.

That distinction explains most surprises. A rule that looks correct in the live DOM can render differently after cloning or rasterization. Style the actual export root and its descendants rather than relying on surrounding application layout, viewport-only positioning, or inherited values from unrelated containers.

A reliable starting example

This example gives the exported element a stable layout, styles a card, keeps that card together, and starts a second section on a new page.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<div id='invoice'>
  <section class='card avoid-break'>
    <h2>Invoice</h2>
    <p class='muted'>Content styled with ordinary CSS.</p>
  </section>
  <section class='page-two'>
    <h2>Terms</h2>
    <p>Payment is due within 30 days.</p>
  </section>
</div>
#invoice {
  box-sizing: border-box;
  width: 100%;
  background: #fff;
  color: #222;
  padding: 24px;
  font-family: Arial, sans-serif;
}
#invoice, #invoice * {
  box-sizing: border-box;
}
.card {
  padding: 16px;
  border: 1px solid #d8d8d8;
  border-radius: 8px;
  background: #fff;
}
.muted { color: #666; }
.avoid-break {
  break-inside: avoid;
  page-break-inside: avoid;
}
.page-two {
  break-before: page;
  page-break-before: always;
}
const element = document.getElementById('invoice');

html2pdf().set({
  margin: 0.5,
  filename: 'invoice.pdf',
  html2canvas: { scale: 2 },
  jsPDF: {
    unit: 'in',
    format: 'letter',
    orientation: 'portrait'
  },
  pagebreak: {
    mode: ['css', 'legacy'],
    before: '.page-two',
    avoid: ['.avoid-break']
  }
}).from(element).save();

Call .from(element) only after the final text, images and classes have been added. The root must remain present and visible while html2canvas renders it.

Style the exported root, not just the application shell

Set dimensions and box sizing explicitly

Use box-sizing: border-box so padding and borders stay inside the declared width. A percentage width can inherit an unexpected size when the clone is rendered, so set a deliberate width on the root and use predictable child widths. Avoid depending on an ancestor that is not included in the element passed to .from().

Make visual properties explicit

Assign backgrounds, text colors, font sizes, line heights, padding and borders on the exported root or its children. Explicit values are safer than inherited theme variables, container queries or styles that exist only in the surrounding application. If a section needs a white page, set background: #fff on that section rather than assuming the browser’s page background will be captured.

Keep layout simple where fidelity matters

Flexbox and grid can work, but complicated responsive rules, viewport units and fixed-position overlays are more likely to expose differences between the live DOM and the cloned DOM. For invoices, reports and certificates, prefer fixed or clearly bounded widths, normal-flow content and straightforward margins. Add export-only classes when the screen layout and PDF layout need different spacing.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #2
Sale
HTML and CSS: Design and Build Websites
  • HTML CSS Design and Build Web Sites
  • Comes with secure packaging
  • It can be a gift option

Prepare media and typography

Use images with explicit dimensions and wait until they have loaded before exporting. Check that web fonts have finished loading; otherwise the clone can fall back to a different font and change line wrapping. Verify every image and font in the actual PDF, not only in the browser preview.

Control page boundaries with CSS

html2pdf.js respects most CSS break-before, break-after and break-inside rules. Include the older page-break-* equivalents when you need compatibility with legacy behavior.

Goal Modern CSS Legacy equivalent Use it for
Start an element on a new page break-before: page page-break-before: always Chapters, terms, appendices
End an element before a new page break-after: page page-break-after: always Cover pages or section endings
Keep an element together break-inside: avoid page-break-inside: avoid Cards, callouts and small tables

Avoid applying break-inside: avoid to very tall content. If the element is taller than a page, the renderer must split it or create an awkward result. Apply the rule to compact units such as a card, not to an entire report.

Use the pagebreak option for precise selectors

The pagebreak option complements CSS and lets you target selectors without adding inline styles.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
pagebreak: {
  mode: ['css', 'legacy'],
  before: '.chapter',
  after: '.chapter-end',
  avoid: ['.card', '.small-table']
}

Choose a mode

Mode Behavior Best fit
css Uses supported CSS break rules Semantic classes and standards-based layouts
legacy Recognizes the legacy html2pdf__page-break class Existing markup that already uses inserted break elements
avoid-all Attempts to keep all elements together Short, card-like documents where broad keep-together behavior is more useful than fine control

You can combine modes, as in ['css', 'legacy']. For a one-off legacy break, insert an empty element after the content that should end the page:

<div class='html2pdf__page-break'></div>

Prefer semantic classes and CSS for new documents. The inserted legacy element is harder to maintain and makes the markup less descriptive.

Prevent common layout failures

Cards split across pages

Add both break-inside: avoid and page-break-inside: avoid to the card, then list the same selector in pagebreak.avoid if you need an explicit html2pdf rule. If the card is taller than the available page area, shorten it, split it into smaller sections, or allow a controlled split.

Headings become separated from content

Wrap a heading and its first paragraph in a small container and apply break-inside: avoid to that container. Applying the rule only to the heading cannot keep the following paragraph with it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
Sale
Web Design with HTML, CSS, JavaScript and jQuery Set
  • Brand: Wiley
  • Set of 2 Volumes
  • A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers

Margins and widths change the number of pages

Remember that margin in the html2pdf settings consumes printable space. A larger margin or a larger font can push one line onto the next page. Set the PDF page format and orientation deliberately, then tune the root width and spacing against that page size.

Content is clipped

Check for fixed heights, overflow: hidden, transforms and absolutely positioned children. Replace fixed heights with natural height where possible. Make sure the exported element contains all descendants you expect; html2pdf cannot capture nodes outside the element passed to .from().

Understand clone-related differences

The project documentation identifies CSS cloning as buggy in some situations. Treat the generated PDF as a separate rendering target:

  • Keep the capture element in the document and visible during rendering.
  • Use export-specific classes for widths, spacing or colors that should differ from the screen.
  • Prefer explicit dimensions over values that depend on the current viewport.
  • Inspect page breaks, images, fonts, backgrounds and colors in the saved file.
  • Test with the longest realistic text, not only a short sample.

Do not assume that a perfect browser screenshot guarantees a perfect PDF. A small export-only stylesheet is often easier to maintain than trying to make every responsive screen rule work in the clone.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Run a repeatable export workflow

  1. Build the complete DOM. Insert dynamic rows, totals and labels before calling html2pdf.
  2. Wait for assets. Ensure images are loaded and fonts are ready.
  3. Apply an export class. Set explicit widths, colors, spacing and any print-only visibility rules.
  4. Mark pagination points. Use break-before, break-after, break-inside and selector options only where needed.
  5. Render with a deliberate page setup. Choose PDF format, orientation, units, margins and canvas scale.
  6. Inspect the file. Check every page at 100 percent, including the last row of tables and the bottom margin.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshooting html2pdf.js styling

Symptom Likely cause Fix
Colors or backgrounds are missing The value is inherited, transparent, or defined only by a theme rule outside the clone Set background and color explicitly on the exported root and affected children.
A card splits despite the CSS rule The selector is not included in the configured pagebreak rules, or the card is taller than a page Add the selector to avoid, include both modern and legacy break properties, or split the card into smaller units.
A section does not start on a new page The break rule is on the wrong element or the selected class is absent in the clone Put the rule on the section itself and verify before: '.selector' matches it.
The PDF has unexpected extra pages Large margins, padding, font metrics or avoid-all keep content together Reduce nonessential spacing, use targeted avoid selectors, and test with the final page format.
Text wraps differently A web font or image was not ready, or the clone received a different width Wait for assets, set an explicit root width, and confirm the font is available before calling .from().
Elements are missing They are outside the exported root, hidden, clipped, or positioned relative to a missing ancestor Move them inside the capture element, remove clipping for export, and use normal-flow positioning where possible.
The result is blurry html2canvas rasterizes the page at a low scale Increase html2canvas.scale, balancing sharpness against memory use and PDF size.

Performance, reliability and file-size trade-offs

Because rendering happens in the browser, very long documents and high canvas scales consume substantial memory. Start with a moderate scale such as 2, capture only the required root, and avoid exporting hidden application panels or unnecessary images. avoid-all can simplify a short document but may create more pages or make layout decisions expensive on a long report; selector-based rules are more predictable for large documents.

For repeatable output, use the same page format, orientation, margins, root width and font-loading sequence on every export. Keep a regression sample containing a short card, a near-page-length card, a forced break, an image and a multi-page table. Compare the actual PDFs after library or stylesheet changes.

Or skip the browser setup

If your goal is a rendered website screenshot or PDF rather than styling an in-browser export yourself, ScreenshotNeo provides a single HTTP request. Its API accepts a URL and returns PNG, JPEG, WebP or PDF; it can load lazy images, wait for a selector, delay or network idle, apply custom CSS or JavaScript, click an element, hide selectors, choose a device or viewport, set dark mode, emulate timezone or geolocation, and capture a CSS-selected element.

Cookie banners, newsletter popups and chat widgets are removed before the shot. Bot checks, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing status. An MCP server exposes take_screenshot, get_page_info and capture_pdf to Claude, Cursor and other MCP clients.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For API parameters and the full option list, see the ScreenshotNeo documentation.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

The free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots, and every feature is available on every plan. Create a free ScreenshotNeo account to try it.

Frequently Asked Questions

Can I use both CSS breaks and html2pdf.js selector breaks?

Yes. Put semantic break-* rules in your stylesheet and use pagebreak.before, after or avoid for selectors that need export-specific control.

What is the purpose of the legacy break class?

html2pdf__page-break is an older marker that inserts a page break after the element. Keep it for existing templates; use semantic CSS classes for new markup.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.