Skip to content

HTML to PDF background color and images not showing: the fix

You render an invoice with a colored header bar and it comes out plain white, or your branded banner image disappears from the PDF. This is not a bug, it is a print default. Here is why HTML to PDF strips background colors and images, and the single setting that turns them back on.

You design an invoice with a navy header bar and a light gray summary box, render it to PDF, and both come out plain white. Or your branded banner image is on the screen but missing from the file. The layout is intact, the text is fine, but every background has vanished. This is one of the most reported HTML to PDF issues, and it catches people off guard because the page looks perfect in the browser. The reassuring part: it is not a bug and it is not your CSS. It is a print default, and there is a single setting that fixes it.

The short version

HTML to PDF drops background colors and background images because print rendering strips them by default, the same behavior you see when you print a web page and the colored areas come out white to save ink. To keep them, turn on background printing: pass printBackground: true in Puppeteer or Playwright, use the print background parameter on your rendering API, and add -webkit-print-color-adjust: exact; print-color-adjust: exact; in your CSS for the elements that must keep their color. With those on, colored headers, gray panels and banner images render in the PDF exactly as they do on screen.

Why backgrounds disappear in the first place

Most HTML to PDF engines render your page through the browser's print path, not its screen path. Printing has a decades-old convention: strip background colors and images so a user does not burn through a color cartridge turning a white page dark. Browsers implement this as the default for print output, so background: navy on your header, a background-color on a table row, and a background-image banner all get suppressed when the page is rendered for paper, or for a PDF, which follows the same path. Your foreground content, text and borders and inline images placed with an <img> tag, comes through fine, which is why the result looks like someone erased only the fills. Nothing in your stylesheet is wrong; the renderer is deliberately ignoring backgrounds because that is what print is supposed to do.

This is also why an inline <img> logo survives but a CSS background-image logo vanishes: the first is real page content, the second is a background, and only backgrounds get stripped. Knowing that distinction tells you exactly which elements will be affected.

The one setting that brings them back

Every browser-based engine exposes a switch that says "render backgrounds too", and turning it on is the whole fix. In Puppeteer or Playwright it is a single option on the PDF call.

// Puppeteer or Playwright
await page.pdf({
  format: "Letter",
  printBackground: true,   // this is the fix
});

With printBackground on, the renderer stops suppressing backgrounds and your colored headers, tinted panels and CSS background images all appear in the PDF. For most people this one line resolves the entire problem. If you are rendering through an API instead of driving the browser yourself, the same control is exposed as a parameter, so you do not have to touch the page's code at all.

When printBackground is not enough: force color on specific elements

Occasionally a background is still dropped even with background printing on, most often because a browser decided to lighten or remove it for legibility, or because a media query is hiding it. The belt-and-braces fix is the CSS color-adjust property, which tells the browser to render an element's colors exactly as authored and not to second-guess them for print.

.invoice-header,
.summary-box,
.badge {
  -webkit-print-color-adjust: exact;   /* Chromium, Safari */
  print-color-adjust: exact;           /* standard */
}

Apply it to the specific elements whose fills matter, the header bar, the status badge, the alternating table rows, and pair it with printBackground at the engine level. Between the two, there is no background color or image a Chromium-based renderer will refuse to include. One more thing to check if a background image specifically is missing: make sure the image URL is absolute and reachable from the renderer, because a relative path or a login-gated asset the browser cannot fetch will simply come back blank.

Watch for a print stylesheet hiding things

If you have an @media print block, remember that the PDF render uses it. It is common to hide navigation, buttons or banners for print, and a rule like .hero { background: none; } or display: none inside that block will strip exactly the backgrounds you now want in the PDF. When a background is missing even with everything above turned on, scan your print stylesheet for a rule that is removing it. The render is doing what your print CSS told it to.

Getting it right through an API

Rendering server side does not change the rule, because the same Chromium print path is involved, so the same background printing switch applies. A good rendering API turns backgrounds on with a parameter, which means you can keep your existing page untouched and still get the colored, branded output.

curl https://api.sitepdf.com/v1/render \
  -H "Authorization: Bearer $SITEPDF_KEY" \
  -F url=https://app.example.com/invoices/8842 \
  -F format=Letter \
  -F print_background=true \
  -F archive=true

Because the engine is a real, current browser, backgrounds render precisely as they do on screen once the flag is set, which is a common reason teams move off older converters whose background handling was unreliable. The full parameter list is on the PDF generator API page. Branded, colorful PDFs like this are often the same reports that later get repurposed for a meeting, and it is easy to turn that report into a slide deck once the PDF itself looks right. For the neighboring layout issues, see the margins, headers and footers guide and the page breaks guide, and convert HTML to PDF covers the basics of a full-page render.

A quick checklist

SymptomFix
Colored header or panel comes out whiteTurn on printBackground or the print background parameter
CSS background image missing, inline img fineEnable background printing; only backgrounds are stripped by default
Background still dropped with printing onAdd print-color-adjust: exact to those elements
Background image blankUse an absolute, publicly reachable image URL
Background missing only in the PDF, not on screenCheck @media print for a rule hiding it

Turn on background printing at the engine level, add print-color-adjust: exact to any element that still loses its fill, and check your print stylesheet is not hiding the very thing you want. With those three in place, your branded colors and images render in the PDF exactly as they look in the browser.

Written by the team building Sitepdf, an HTML to PDF API that archives every page it renders. The in-browser converter is free to try; early access locks the launch pricing.

§ Early access

Get on the early-access list

The API opens to the list first, in order. Early access locks the planned launch rates for 12 months. No card required, launching soon.

Render + archive, one API