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.

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

Put the declarations directly on the element that must be styled, inside its style attribute, before passing the HTML string to your PHP PDF renderer. For example:

<div style="font-family: DejaVu Sans, sans-serif; font-size: 12pt; color: #222; padding: 8pt;">Invoice text</div>

This works with Dompdf, mPDF and TCPDF because each documents support for element-level style attributes. The important qualification is that these libraries implement their own print-oriented CSS subsets, not a complete browser engine.

What inline CSS means in a PHP PDF workflow

Inline CSS is a declaration placed on the HTML element itself:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<p style="font-size: 11pt; line-height: 1.4; color: #333;">Thank you for your order.</p>

Your PHP code must include that attribute in the exact HTML string sent to the renderer. A stylesheet loaded by your browser is not automatically available to PHP, and a browser preview is not proof that the PDF engine supports the same property.

The style attribute is the most local author rule. When an element’s output is wrong, put the declaration on that element, use a print-safe unit such as pt, mm or px, and check the generated PDF in the target library.

Dompdf: add styles to the HTML before rendering

Dompdf is largely CSS 2.1 compliant. It reads element style attributes, <style> blocks and external stylesheets, but it does not support CSS flexbox or Grid. Table rows also cannot be split across pages.

Complete Dompdf example

<?php
require __DIR__ . '/vendor/autoload.php';

use DompdfDompdf;

$dompdf = new Dompdf();
$html = '<!doctype html>
<html>
<head>
  <meta charset="utf-8">
</head>
<body>
  <h1 style="font-size: 18pt; color: #1f2937; margin-bottom: 10pt;">Invoice</h1>
  <p style="font-size: 10pt; line-height: 1.4;">Thank you for your order.</p>
  <div style="border: 0.5pt solid #d1d5db; padding: 8pt; margin-top: 12pt;">
    <strong style="color: #111827;">Total: $125.00</strong>
  </div>
</body>
</html>';

$dompdf->loadHtml($html);
$dompdf->setPaper('A4');
$dompdf->render();
$dompdf->stream('invoice.pdf', ['Attachment' => false]);

For remote images, fonts or stylesheets, enable remote loading deliberately. Dompdf requires isRemoteEnabled=true, a working cURL extension or allow_url_fopen, and local files must remain inside its configured chroot. Treat this as a security decision, not a default fix for every missing asset.

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

Remote-resource checklist

  • Confirm the URL is reachable by the PHP process, not only by your desktop browser.
  • Enable remote access in Dompdf’s options only when required.
  • Keep local assets under the allowed chroot.
  • Use absolute, deterministic paths and verify file permissions.

mPDF: inline declarations override stylesheet rules

mPDF documents this author-source priority: HTML attributes, stylesheet rules, then inline CSS. Consequently, an element’s style attribute has the highest priority among those sources.

Minimal mPDF example

<?php
require __DIR__ . '/vendor/autoload.php';

$mpdf = new MpdfMpdf();
$html = '<p style="font-family: sans-serif; font-size: 11pt; color: #333;">Inline mPDF text</p>';
$mpdf->WriteHTML($html);
$mpdf->Output('invoice.pdf', MpdfOutputDestination::INLINE);

Keep shared CSS separate when it is genuinely shared

Pass a stylesheet first in header-CSS mode, then pass the document body in HTML-body mode. Use inline CSS for a one-off exception or a value generated from application data.

<?php
$stylesheet = file_get_contents(__DIR__ . '/print.css');
$mpdf->WriteHTML($stylesheet, MpdfHTMLParserMode::HEADER_CSS);
$mpdf->WriteHTML($html, MpdfHTMLParserMode::HTML_BODY);

Do not send arbitrary user-supplied HTML and CSS directly to mPDF. Its manual warns that input must be vetted and sanitized more rigorously than normal browser-level sanitization.

TCPDF and tc-lib-pdf: use the HTML cell API for flowing content

TCPDF’s cascade resolves global CSS, document <style> blocks and element style attributes. Its renderer supports inheritance, selectors, box-model properties, floats, inline-block and page-break controls, but it still implements a library-specific subset of CSS.

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

Flowing HTML with addHTMLCell()

<?php
$pdf->setGlobalCSS('body { font-family: helvetica; font-size: 10pt; }');
$pdf->addHTMLCell(
    html: '<p style="color:#333; margin: 4pt 0;">Inline TCPDF text</p>',
    posx: 15,
    posy: 20,
    width: 180
);

Use addHTMLCell() when content may flow across pages. Use getHTMLCell() when you need to place the generated PDF operators yourself and manage their placement explicitly.

Choosing the right injection point

Need Best approach Reason
One element needs a unique value style attribute It is local and has high author-source priority.
Many documents share rules Embedded or library-loaded stylesheet Central maintenance is easier.
Global defaults in TCPDF setGlobalCSS() Applies a baseline before element overrides.
Data-dependent colors, widths or spacing Generate a sanitized inline value The value can be computed per record.

Inline CSS is not a workaround for unsupported layout engines. If a property is outside the renderer’s subset, moving it into style will not make it work.

CSS that survives PDF conversion

Use physical or explicit units

Prefer pt for typography and print measurements, mm for paper dimensions and px when a renderer’s pixel mapping is acceptable. Avoid relying on viewport units or browser-only responsive behavior.

Replace browser layout assumptions

For Dompdf, replace flexbox and Grid with normal block flow or tables. Tables are also useful for invoices and other columnar records, but test long rows because Dompdf cannot split a table row across pages.

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

Control page breaks deliberately

Test headings, images, long paragraphs and tables at realistic lengths. A layout that looks correct with three rows can fail when a row crosses a page boundary. Use the page-break controls supported by your chosen renderer rather than assuming browser print CSS is fully implemented.

Fonts and images

Check that the font is available to the renderer and that image paths resolve from the server. Missing assets are often path, permission or remote-access problems rather than CSS problems.

Build the HTML safely

If style values come from application data, allow-list the values and escape text before concatenating HTML. Do not insert raw user input into a style attribute or into a complete document. For mPDF in particular, sanitize untrusted HTML and CSS before calling WriteHTML().

<?php
$title = htmlspecialchars($invoiceTitle, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
$color = in_array($statusColor, ['#166534', '#b91c1c'], true)
    ? $statusColor
    : '#374151';

$html = '<h1 style="color: ' . $color . '; font-size: 18pt;">'
      . $title
      . '</h1>';

Escaping the text does not validate CSS. Validate each dynamic CSS value separately, and avoid accepting arbitrary declarations from users.

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

Troubleshooting inline CSS that disappears

The PDF has no styling

  • Log or inspect the final HTML string. Confirm the style attribute is present before rendering.
  • Check for malformed quotes or unescaped user data that terminated the attribute.
  • Verify that you are calling the renderer’s HTML API, not a plain-text or image API.

It works in the browser but not in the PDF

  • Check whether the property is supported by the renderer’s CSS subset.
  • Replace flexbox or Grid with block flow or a table when using Dompdf.
  • Replace viewport-dependent values with pt, mm or px.

Images, fonts or external CSS are missing

  • Use a server-readable absolute path or a reachable URL.
  • For Dompdf, configure remote loading and chroot correctly.
  • Check PHP permissions, TLS certificates and redirects from the server environment.

Styles are overridden

  • Place the declaration on the element whose output is wrong.
  • In mPDF, remember that inline CSS outranks stylesheet rules.
  • In TCPDF, inspect global CSS, document styles and inherited values together.

Content overlaps or breaks across pages

  • Test with production-length text and the actual paper size.
  • Reduce fixed heights and large padding.
  • Split complex content into smaller blocks or rows.
  • For Dompdf, redesign rows that cannot fit on one page.

Performance, reliability and testing

Inline CSS can reduce dependency on stylesheet paths, but it does not eliminate rendering cost. Large HTML strings, high-resolution images and embedded fonts increase memory and processing time. Generate only the CSS needed for the document, reuse shared stylesheet content where practical, and avoid repeatedly loading the same assets inside loops.

Test the actual renderer in a repeatable suite. Include:

  • single-page and multi-page documents;
  • long table rows and page boundaries;
  • missing and remote assets;
  • non-ASCII text and the fonts required to display it;
  • empty values, unusually long names and dynamic colors;
  • the final paper size, margins and orientation.

Keep browser screenshots as a visual reference, not as the acceptance test. The PDF engine’s supported CSS and pagination behavior determine the result.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If your goal is a clean visual capture of a web page rather than a PHP-rendered document, ScreenshotNeo provides a single HTTP request for PNG, JPEG, WebP or PDF output. Its API accepts cookie and consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets; each step can be turned off. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers. An MCP server exposes take_screenshot, get_page_info and capture_pdf to Claude, Cursor and other MCP clients.

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

One-call cURL example

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

See the ScreenshotNeo documentation for all capture options, including full-page lazy-image loading, CSS-selector element capture, device presets, custom CSS and JavaScript, waits, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, TTL caching, signed links, asynchronous webhooks, bulk capture and usage reporting.

ScreenshotNeo’s free plan includes 1,000 shots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan. Sign up for the free plan.

FAQ

Can inline CSS replace a stylesheet entirely?

Yes for a small document, but shared rules are usually easier to maintain in a stylesheet while inline declarations handle per-element exceptions.

Does inline CSS guarantee browser-identical output?

No. Dompdf, mPDF and TCPDF each support a renderer-specific subset, so the generated PDF must be tested independently.

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

Which library should I use?

Choose based on the CSS coverage, cascade controls, pagination, asset policy and HTML API your document requires; no single library provides full browser behavior.

Frequently Asked Questions

Should I put the style attribute before or after the class attribute?

Attribute order does not determine CSS priority. The declaration’s location on the element and the renderer’s cascade rules matter.

Why does a remote font load in my browser but not in PHP?

The PHP process may lack network access, cURL or URL-stream support, permission to read the file, or the renderer’s explicit remote-resource configuration.

Can I use JavaScript to fix layout before PDF conversion?

Do not assume it will run. These PHP renderers are not full browser engines; produce stable HTML and CSS that the selected library documents as supported.

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.

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.