Free tools Windows power users keep installed
One-click scans. No signup required.
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:
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstall<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.
#1 Best Overall
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.
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.
Rank #2
<?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.
Recommended Free Tools
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.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →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.
Rank #4
Troubleshooting inline CSS that disappears
The PDF has no styling
- Log or inspect the final HTML string. Confirm the
styleattribute 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,mmorpx.
Images, fonts or external CSS are missing
- Use a server-readable absolute path or a reachable URL.
- For Dompdf, configure remote loading and
chrootcorrectly. - 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.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.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →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.
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.
Quick Recap
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.

