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

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

To apply CSS when converting HTML to PDF, put one-off declarations in an element’s style attribute, add reusable rules in a <style> block or linked stylesheet, or pass a stylesheet through the converter’s API. The right method depends on the rendering engine: Puppeteer generates PDFs using print media by default, while WeasyPrint supports document stylesheets and API-supplied CSS with cascade rules that can affect which declaration wins.

Before changing CSS, identify the converter and version, decide whether the PDF should follow print or screen styles, and check the PDF options that can override page sizing. Then inspect the generated PDF itself; a rule that works in a browser is not guaranteed to render identically in every PDF engine.

Choose the CSS method that your PDF converter supports

HTML-to-PDF converters do not all expose styling in the same way. Start by identifying the engine and version, then decide where the relevant rule belongs:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Inline style attribute: Put a declaration directly on an element, such as <p style="color: #222; margin: 0">Text</p>. This is handy for a one-off change to a specific element.
  • Embedded stylesheet: Put reusable rules in a <style> element in the HTML document.
  • Linked stylesheet: Reference a CSS file from the HTML. The renderer must be able to access it when generating the PDF.
  • API-supplied stylesheet: Some engines let you pass CSS separately from the HTML. WeasyPrint supports this approach.

These are different ways to provide CSS, not guarantees that every property or browser behavior will be supported. Check the chosen engine’s documentation for its CSS support and verify the output PDF.

Apply a one-off rule with an inline style

For a rule that applies to one element, add CSS declarations to its style attribute:

<p style="color: #222; margin: 0">Invoice total: $125.00</p>

The attribute uses normal CSS declaration syntax: property, colon, value, and a semicolon between declarations. Inline styling keeps the rule next to the element it affects, but it can become awkward when the same formatting is repeated across a document. For repeated or document-wide styling, a stylesheet is usually easier to maintain.

This is a general HTML/CSS pattern. The official material cited here does not compare how every PDF engine handles style attributes, so confirm that the selected renderer supports the properties you use.

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

Use embedded or linked stylesheets for reusable rules

Embedded CSS

An embedded stylesheet keeps the rules in the HTML being converted:

<style>
body { font-family: sans-serif; color: #222; }
h1 { margin-bottom: 0.5em; }
</style>

WeasyPrint documents embedded <style> elements as an author stylesheet source. If your CSS seems missing, make sure the stylesheet is actually included in the HTML passed to the renderer.

Linked CSS

A linked stylesheet separates presentation from HTML, which can help when many documents share the same design. Confirm that the renderer can retrieve the stylesheet and any referenced assets at conversion time. A browser preview on your machine does not prove that a remote or local stylesheet will be available to a separate rendering process.

Pass a stylesheet to WeasyPrint

WeasyPrint’s first-steps guide demonstrates supplying a CSS string to HTML.write_pdf() through the stylesheets argument. The following example creates a PDF named output.pdf from an HTML string:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
from weasyprint import HTML, CSS

html = """
<!doctype html>
<html>
  <head><title>PDF example</title></head>
  <body><p>Invoice total: $125.00</p></body>
</html>
"""

HTML(string=html).write_pdf(
    "output.pdf",
    stylesheets=[CSS(string="body { font-family: serif !important }")]
)

The API-supplied stylesheet is a user stylesheet. WeasyPrint documents that user stylesheets have lower cascade priority than author stylesheets, such as rules in the HTML. If a supplied rule does not take effect, inspect stylesheet origin and selector specificity; use !important only when necessary to address the cascade, rather than assuming the property is unsupported.

Consult the WeasyPrint first-steps documentation for the API details, and its stylesheet-origin documentation for cascade behavior.

Set print or screen styling in Puppeteer

Puppeteer’s Page.pdf() generates a PDF using the print CSS media type. That means print-specific rules can be active even if the page looked different in a normal browser view. If you specifically want the screen stylesheet, emulate screen media before calling page.pdf():

await page.emulateMediaType('screen');
await page.pdf({ path: 'output.pdf' });

Use print media when the intended output is a document designed for printing. Choose screen media only when the screen layout is the desired PDF appearance; it does not simply make all browser rendering differences disappear. Puppeteer also modifies colors for printing by default. Its documentation identifies -webkit-print-color-adjust as the property for forcing exact colors when that is required.

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

See the Puppeteer Page.pdf() documentation for its media behavior and print-color notes.

Make CSS page size and PDF options agree

Page dimensions can be controlled in CSS with @page and through PDF-generation options. In Puppeteer, preferCSSPageSize controls whether a CSS @page size takes priority over the PDF width, height, or format options. The documented default is false. If a page is the wrong size, check both places rather than changing unrelated layout CSS.

await page.pdf({
  path: 'output.pdf',
  preferCSSPageSize: true
});

Set this option when the CSS page size should take precedence. If the PDF options should determine the size instead, do not assume that an @page declaration will override them. Refer to the Puppeteer PDF options documentation for the option and its default.

Diagnose CSS that does not appear in the PDF

  1. Confirm the renderer and version. Engine-specific behavior is not interchangeable. Use documentation for the converter that actually creates the PDF.
  2. Check the media type. In Puppeteer, PDF generation uses print media by default. If the intended design is the screen layout, call page.emulateMediaType('screen') before page.pdf().
  3. Confirm the stylesheet reaches the renderer. Check that embedded CSS is in the HTML supplied to the converter, or that the linked CSS file is accessible from the renderer’s environment.
  4. Inspect the cascade. In WeasyPrint, API-provided user stylesheets have lower priority than author stylesheets. Check origin and specificity before escalating to !important.
  5. Check page-size sources. Compare the CSS @page rule with Puppeteer’s PDF size options and the preferCSSPageSize setting.
  6. Check property support. A property or browser feature may not be supported the same way by every PDF renderer. WeasyPrint documents supported and unsupported features; consult the matching documentation for your engine.
  7. Inspect the actual PDF. Render a representative document after the change and check layout, colors, page breaks, and assets. Documentation describes features and defaults; it does not establish how an unspecified HTML document will render.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Choose a converter based on the document’s needs

The relevant choice is not simply “browser” versus “library.” Decide based on the output you need and the controls the engine provides:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Does the document need browser print-media behavior, or a paged-document workflow?
  • How will HTML, stylesheets, fonts, images, and other assets be supplied and made accessible?
  • Does the renderer support the CSS features and page-break behavior the document depends on?
  • How will page size, margins, and print colors be controlled?
  • Has a representative output been rendered and checked using the selected engine and version?

The cited documentation establishes Puppeteer’s print-media PDF behavior and page-size option, and WeasyPrint’s stylesheet sources and documented feature set. It does not establish a complete performance or compatibility ranking between them; test the engine against the document you need to produce.

Or skip the browser setup

If your task is to capture a web page as an image or PDF rather than build and style a custom HTML document, ScreenshotNeo offers a one-request screenshot API. It is not a replacement for configuring CSS in a PDF renderer when you control the HTML and need a particular document layout.

For example, this cURL request captures a web page as WebP; replace the target URL as needed. See the ScreenshotNeo API documentation for the request options.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

ScreenshotNeo accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and the response identifies the page verdict and billing status in headers. Its MCP server provides screenshot and page-information tools for AI agents. The free plan includes 1,000 shots a month with no card; paid plans start at $5 for 3,000 shots.

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.

Sign up for ScreenshotNeo’s free plan to try 1,000 screenshots a month with no card.

Frequently asked questions

Does inline CSS guarantee that a rule will appear in the PDF?

No universal guarantee is established here. Support and rendering behavior depend on the converter and its version; check that engine’s CSS documentation and inspect a generated PDF.

Why does Puppeteer’s PDF look different from the browser page?

Page.pdf() uses print media by default, so print styles may apply instead of screen styles. Emulate screen media before PDF generation only if the screen layout is the intended result.

Why is my WeasyPrint API stylesheet being overridden?

An API-supplied stylesheet has user origin, which has lower cascade priority than author stylesheets. Check stylesheet origin and selector specificity, then consider whether !important is appropriate.

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.

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.