← dompdf.js Studio

CSS Colors & Gradients in dompdf.js: A Complete Rendering Guide

Many developers who generate PDFs with dompdf.js settle for plain black text on a white background, but color and gradients are the fastest way to make a document look professional: a brand-colored table header, a gradient card, status tags that use color to communicate state. How you write colors directly affects readability, brand consistency, and how credible the document looks to clients and stakeholders. This article systematically covers how dompdf.js handles the CSS color and gradient family, including linear-gradient, radial-gradient, and the repeating variants, from basic color values and alpha transparency to gradient angles and color stops. You will get working, renderable code examples, honest guidance on fallback strategies, and a rundown of the pitfalls that trip up developers who migrate web templates into PDF output. Whether you build reports, invoices, resumes, or product manuals, mastering these details will visibly raise the visual quality of your generated PDFs and spare you the embarrassing situation where a page looks great in the browser but falls apart in the PDF, saving hours of trial-and-error debugging in the process.Beyond the syntax, you will learn how the engine maps colors into the PDF color space, why a defensive background-color layer protects your layout, and how to verify color fidelity against a printed proof. The guidance is written for developers who want deterministic output: every recommendation is grounded in how the renderer actually works, not in habits borrowed from browser-only styling. Apply the patterns here to invoices, reports, and marketing documents alike, and keep the troubleshooting table handy as a quick reference whenever a gradient or a color behaves unexpectedly in your next export.

Color Value Formats and Support

dompdf.js parses CSS colors directly and supports the full set of syntaxes that browsers do: named colors such as red or skyblue, hexadecimal values like #3498db, and functional notations including rgb(), rgba(), hsl(), and hsla(). Whatever you write in your daily web development carries over to the PDF renderer without any conversion layer, so existing stylesheets can be reused in PDF templates as-is, which keeps the learning curve close to zero.

Hexadecimal notation is the most precise and the most common choice for brand colors, while the alpha channel of rgba() gives you transparency control that forms the basis of gradients, watermarks, and overlay effects. hsl() describes colors by hue, saturation, and lightness, which makes it convenient for building a coherent palette, for example deriving lighter background tints and darker text variants from one brand hue so the whole document stays tonally consistent.

One important caveat: colors are ultimately converted into the PDF color space, so stick to sRGB values and avoid exotic wide-gamut colors that can shift between monitors and printers. For strict brand-color requirements, verify against a printed proof rather than trusting the screen preview, because the actual output device is the only reliable judge of whether the color is correct for delivery.

One practical habit worth adopting is centralizing your palette with CSS custom properties: define --brand: #3498db, --success: #27ae60, and --danger: #e74c3c once at the top of the template, then reference them throughout. When the brand refreshes, one edit updates every page of every exported document, and the template stays readable because the semantic names document their own purpose. Custom properties also make it easy to generate tints by hand when you need a lighter header background or a softer tag color.

Precision matters more than it seems: #3498db and rgb(52, 152, 219) are the same color, but mixing notations in one template makes audit and maintenance harder. Choose one primary notation for the template, hex for brand colors and rgba for anything with alpha, and document the choice in a comment. If you ever need to verify a color against a brand guideline, convert it to hex and compare against the official value rather than eyeballing two screens.

linear-gradient in Depth

linear-gradient is the most frequently used gradient type, smoothly transitioning a background from one color to another. dompdf.js supports both angle values and direction keywords such as to right, to bottom, and 135deg, plus any number of color stops with percentage positions, matching browser behavior closely enough that existing web styles can be migrated without modification.

Color stops are the heart of any gradient: linear-gradient(90deg, #3498db 0%, #2ecc71 100%) transitions from blue to green left to right, and the stop percentages control the pace of that transition. Adding a third or fourth stop produces segmented transitions that work beautifully for gradient dividers, data bars, or color scales, giving you more expressive power than a flat block of color while remaining a single CSS declaration.

A defensive writing habit pays off in PDF rendering: declare background-color first as a fallback layer and put the gradient in background-image on top. If the engine ever fails to interpret an exotic gradient syntax, the solid background color still renders, so the page never breaks visually. This layered approach is the standard defensive technique across rendering engines and doubles as your first diagnostic when a gradient misbehaves.

Multiple background layers let you combine gradients with images and solid colors in one declaration: background-image: linear-gradient(...), url(logo.png), where the first layer paints on top. This is how you place a subtle brand tint over a product photo, or how you build a header band with a gradient plus a right-aligned pattern. The order of layers is the order of painting, top layer first, and each layer can carry its own position and size.

Gradient direction keywords and angles are interchangeable: to right is exactly 90deg and to bottom right is 135deg, so pick whichever reads better in context. When you need a gradient to align with a rotated element, angles are the reliable choice because keywords always resolve against the element's own box. For consistent results across templates, standardize on angles in your style guide and use keywords only for the simplest horizontal and vertical cases.

Radial and Repeating Gradients

radial-gradient expands outward from a center point, which makes it ideal for highlights, glows, and button textures. You can specify the shape (circle or ellipse) and the center position (at center, at top right, and so on). dompdf.js renders radial gradients reliably, so they are a practical way to build accent blocks, circular badge backdrops, and decorative elements that add depth to an otherwise flat document.

repeating-linear-gradient and repeating-radial-gradient repeat a gradient unit at a fixed rhythm, which suits diagonal watermarks, striped table headers, progress-bar textures, and color-band dividers. They are far more efficient than hand-authoring dozens of solid color blocks, and the color transitions look smoother, making them one of the highest-leverage techniques for raising the visual quality of bulk-generated documents.

When you use repeating gradients, keep the cycle units consistent: mixing px and percentages makes stripe widths unpredictable across different page sizes. Use px for fixed-size containers and percentages for fluid ones so the output stays deterministic. Also keep stripe widths reasonably large, because extremely fine stripes can blur into a muddy mess when the PDF is printed on paper.

Radial gradients support size keywords that change the shape subtly: closest-side makes the gradient fit the nearest edge, farthest-corner stretches it to the farthest corner, and the default ellipse shape adapts to the element's aspect ratio. These keywords matter when you place highlights on buttons or badges, because the same gradient code looks different on a wide banner than on a square tag, and explicit sizing removes the guesswork.

Gradients can also decorate text and borders: background-clip: text with a gradient background paints the glyphs themselves, and a gradient behind a transparent border creates a colored frame that changes across the element. Both techniques render in dompdf.js and give designers the kind of finishing touches that separate a polished report from a plain one, while staying pure CSS with no image assets to ship.

Code Example: Brand Gradient Card and Status Tags

The example demonstrates the three layers of defensive styling: a solid background-color that guarantees the card is visible even if the gradient fails, a linear-gradient that carries the brand look, and a repeating gradient that builds the striped bar without any image asset. Note that the status tags use solid colors for reliability, since tag colors carry semantic meaning and should never depend on gradient support. Run the code as-is, then experiment with the angle and the stops to see how each parameter changes the rendered output.

A good exercise after running it: remove the background-color fallback and export again, then restore it and compare. You will see exactly how the fallback behaves when the gradient is present, which builds the intuition for writing defensive styles by default. Once comfortable, try swapping the gradient for a radial version on the card and a repeating radial version on the bar, and observe how the same template shifts character without any structural change.

import { DomPDF } from 'dompdf.js';

const html = `
  <style>
    .card {
      background-color: #eaf2fb;  /* fallback base color */
      background-image: linear-gradient(135deg, #3498db 0%, #2ecc71 100%);
      border-radius: 12px;
      padding: 24px;
      color: #fff;
    }
    .tag {
      display: inline-block;
      padding: 4px 12px;
      border-radius: 999px;
      font-size: 12px;
      color: #fff;
    }
    .tag-ok   { background-color: #27ae60; }
    .tag-warn { background-color: rgba(243, 156, 18, 0.85); }
    .bar {
      height: 14px;
      background-color: #ecf0f1;
      background-image: repeating-linear-gradient(
        90deg, #3498db 0 40px, #5dade2 40px 80px
      );
    }
  </style>
  <div class='card'>
    <h1>Monthly Revenue Overview</h1>
    <p>Gradient background with a solid fallback underneath</p>
  </div>
  <p>
    <span class='tag tag-ok'>Normal</span>
    <span class='tag tag-warn'>Warning</span>
  </p>
  <div class='bar'></div>`;

const pdf = new DomPDF({ format: 'A4', margin: '20mm' });
pdf.addPage(html, { format: 'A4' });
pdf.save('gradient-demo.pdf');

Practical Use Cases for Colors and Gradients

Reports benefit immediately: color the table header with a brand gradient, alternate rows with a light tint like #f8f9fa, and emphasize the totals column. Invoices can color amounts in red and tax tags in green, while resumes gain a gradient title bar and skill bars built from repeating gradients. Each of these is one or two lines of CSS, yet the perceived quality jump is immediate and obvious to clients.

Gradients are best used for decorative surfaces; body text should stay high-contrast dark so it prints crisply. Be cautious with large dark gradient areas behind white text: some printers render the white glyphs grayish because of ink limits, so verify with a printed proof. Even light gradients deserve a print check, since large tinted areas can show banding or uneven ink coverage on some devices.

Color also carries semantics in documents: red for exceptions, green for normal, orange for warnings. Manage your palette centrally in the template so color definitions live in one place and a single edit propagates everywhere. This avoids scattered magic color values, keeps the whole document consistent, and makes future brand adjustments trivial instead of a hunting expedition.

Beyond the obvious visual benefits, color and gradients solve real reading problems: a gradient table header separates the header band from data rows more strongly than a flat fill, and tinted row alternation keeps the eye on the correct line in dense tables. In dashboards and KPI reports, gradient progress bars communicate magnitude at a glance, and semantic colors on totals let reviewers scan for exceptions without reading every number.

Accessibility deserves a place in the design process: color is a channel, not the only channel. If the document will be read in grayscale, printed on a monochrome printer, or consumed by someone with color-vision deficiency, every color-coded state should also carry a textual or iconographic cue. A red amount with a warning symbol and a green amount with a check mark communicate the same information in any output environment.

Common Problems and Fallback Strategies

Q: The gradient renders as a flat color in the PDF? A: Check whether a background-color fallback is masking it, and whether the gradient syntax is complete (direction, stops, balanced parentheses). Temporarily remove the fallback color to see the gradient alone, then restore it once confirmed; this isolates the problem in a minute or two.

Q: Colors differ from the browser? A: This is almost always a color-space mismatch. Normalize everything to sRGB, avoid display-specific wide-gamut values, and prefer hex and rgba, which are the most stable notations. hsl() can produce small rounding differences between engines, so switch to hex when color accuracy matters.

Q: White text on a dark background prints gray? A: Printer ink limits are usually the culprit. Reduce the background saturation, or switch to a light background with dark text; alternatively ship a print-specific style variant that swaps in the safer combination while keeping the screen look.

The general fallback principle: missing colors never crash rendering, they degrade to default black or transparent. So never encode critical information in color alone. Pair color with icons, text, or borders as a second channel, and the document stays usable in grayscale and black-and-white printing, which is the mark of a professionally engineered template.

A subtle failure mode appears with very large gradients: the transition can show visible banding, stepped bands of color where the gradient should be smooth, especially between similar hues. The fix is to add intermediate color stops so each step covers less distance, or to choose adjacent colors with slightly higher contrast so the bands are less perceptible. Banding is a rendering reality, not a bug, and knowing the mitigation saves a round of confusing debugging.

When verifying color output, build a one-page test document containing every color and gradient used in the template, with labels, and export it to PDF. Compare against the browser rendering at 200 percent zoom, then print a proof if the document will be printed. This quick audit catches mismatches before they reach a customer and doubles as a regression test whenever the template or the library version changes.

⚡ 现场演示(点击生成 PDF)

下面的按钮用 dompdf.js 在浏览器端实时生成 PDF,无需后端:

Hello from dompdf.js!

这是由 dompdf.js 渲染的示例 PDF 内容。