Why Your Visualforce PDF CSS Isn't Working (And How to Stop Fighting It)

CSS that looks perfect in the browser silently breaks when a Visualforce page renders as PDF. Here is why it happens, the workarounds teams try, and a native approach that avoids the problem entirely.
You build a Visualforce page. It looks exactly right in the browser. You add renderAs="pdf", open the output, and half your styling is gone. Borders vanish. Columns collapse. A font weight is ignored. Background colors work but font-weight: bold doesn't. It is one of the most common, and most frustrating, surprises in Salesforce document generation.
Here is what is actually happening, and why no amount of CSS tweaking fully fixes it.
Why Visualforce PDF ignores your CSS
When a browser renders a Visualforce page, it uses a modern, fully up-to-date rendering engine. When Salesforce converts that same page to a PDF, it does not use a browser. It uses an older, embedded PDF rendering engine (Flying Saucer) that only understands CSS 2.1.
That single fact explains almost every symptom:
- Modern CSS is silently dropped. Flexbox, CSS grid,
background-size, manytransformandbox-shadowrules, and most CSS3 selectors either do nothing or render unpredictably. There is no error: the property is just ignored. - The Lightning Design System (SLDS) doesn't survive. SLDS is built on modern CSS, so a page styled with it renders one way on screen and another way in the PDF.
- Fonts are limited. Only a small built-in font set is reliably supported. Custom and web fonts frequently fail, and some fonts drop bold/italic styling for certain character sets.
- Images misbehave.
max-width/max-heighton a logo may be ignored, so the image renders at full size; base64/inline images that display in the browser can fail to appear in the PDF.
None of this is a bug in your CSS. It is the gap between what the browser can render and what the PDF engine can render.
The workarounds teams try
Because the constraint is in the engine, every fix is a workaround rather than a solution:
- Maintain a second, simplified layout that exists only to survive the PDF engine: legacy CSS 2.1, inline styles instead of classes, tables for layout. Now you have two copies of the same document to keep in sync.
- Rewrite CSS as inline
styleattributes because class-based CSS is applied inconsistently. - Swap fonts to a supported family and accept the visual compromise.
- Attach images as files and merge them in, instead of embedding them, because inline rendering fails.
Each works for the test case. Each adds a permanent piece of maintenance that can drift out of sync the next time the document changes.
A different approach: stop authoring for a legacy engine
The root problem is that you are hand-writing CSS against a rendering engine you don't control and that hasn't moved in years. ZeroExport takes that engine out of the equation.
Instead of writing a Visualforce page and hoping the PDF engine cooperates, you design the document in a native, WYSIWYG builder inside Salesforce. The document is defined structurally, not as a flat page you style by trial and error. That changes the failure modes that this whole article is about:
- You design visually, so there is no "looks right in the browser, breaks in the PDF" gap to debug.
- Layout is structure-aware. When a field is missing, the layout reflows (a three-column row becomes two columns) instead of leaving the broken gaps that plague hand-styled pages.
- Problems surface as a build-time warning, before the document ships, rather than being discovered when someone opens the file.
- Every generation is deterministic. Once the template is saved, the same inputs produce the same document: no version-to-version rendering surprises.
The point is not that one more CSS trick will finally work. It is that you no longer maintain a fragile pass-through layout whose only job is to appease an aging renderer.
One honest note: if your requirement is pixel-exact control over where every page breaks, or rendering enormous documents at high volume, those are platform-level concerns worth evaluating directly for any tool. This article is about the everyday styling failures of
renderAs="pdf", which a native, structure-aware builder sidesteps by design.
FAQ
Why does my CSS work in the browser but not in the Visualforce PDF?
Because they use different rendering engines. The browser uses a modern engine; the PDF conversion uses an older embedded engine that only supports CSS 2.1. Modern CSS properties are silently ignored in the PDF, which is why the same page looks correct on screen and broken in the file.
Can I use flexbox or CSS grid in a Visualforce PDF?
No, not reliably. The PDF engine predates those layout modules. Teams fall back to table-based layouts and inline styles, which is exactly the kind of maintenance workaround a native document builder avoids.
Why does font-weight: bold not work in my Visualforce PDF?
It is a known limitation tied to the PDF engine's font handling: certain font families support the right characters but strip bold or italic styling. Switching to a supported font is the common workaround.
Is there a way to generate styled Salesforce PDFs without fighting Visualforce CSS?
Yes. A native document generation tool like ZeroExport lets you design the document in a WYSIWYG builder inside Salesforce, so you are not hand-authoring CSS against a legacy PDF engine at all.
Related Reading
Ready to try ZeroExport?
Start generating documents directly in your Salesforce org. No integrations, no setup overhead, no complexity.