A CSS mesh gradient is a colorful background built by stacking four standard radial-gradient layers over a single base color, where each layer fades from a chosen color at its center to transparent at a fixed percentage so the colors blend only where the circles overlap. The result looks like a soft, painterly mesh but is generated entirely from CSS — no canvas, SVG, raster image, or external library is required. Because the background is composed of declared radial gradients, it scales with whatever element it is applied to without adding an HTTP request, and every color stays editable directly in the stylesheet. The technique works inside any modern browser that supports the CSS Images Level 3 radial-gradient() function, and the output is plain enough to read, paste, and version-control like the rest of your CSS. The fixed corner positions, transparent terminal stops, and bounded fade spread are what make the result predictable enough to ship: every input is narrowly constrained, and the generated declaration is the same CSS the live preview paints with.

What a CSS Mesh Gradient Actually Is
"Mesh gradient" in design tools usually means a true mesh surface — a grid of color stops that interpolate between control points. Adobe Illustrator and Figma can produce these because they render to a raster or vector canvas where pixel- or vertex-level interpolation is possible. CSS does not yet expose that model as a native property, so when developers talk about a "CSS mesh gradient" they mean something more modest: a stack of overlapping radial gradients that, combined, gives the eye a similar soft, multicolored impression.
This distinction matters because the layered approach has specific, predictable limits. Each radial gradient is a circle painted with one color at the center that fades to transparent before the circle ends. The browser composites all four circles from front to back, with the first listed gradient closest to the viewer and the base color filling everything that none of the circles cover. The visual effect approximates a mesh, but it is not a continuous interpolation field, and moving a control point in Figma is not the same operation as editing a color in CSS.
How the Layered Radial Approach Works
The technique relies on four radial-gradient() functions declared inside the background-image property, separated by commas, plus one background-color value. Each function uses the explicit circle shape syntax and a fixed percentage-based center point, so the same declaration produces the same layout in any browser that supports the standard. The six-digit hexadecimal color inputs the browser provides match the format the generator validates, so the values you select round-trip into the output without conversion.
The four fixed positions anchor the layers near the corners of the element: 15% 20%, 85% 15%, 20% 85%, and 80% 80%. Each gradient begins with its selected color at 0% and transitions to transparent at the chosen spread percentage. Because the terminal stop is transparent, areas covered by only one layer show that layer's color blended toward the base, while areas where two or three layers overlap mix all participating colors together.
For the layered mesh to remain predictable and readable, every input is constrained. Colors must be six-digit hexadecimal values, and the spread must be an integer between 10 and 90. Those bounds keep the generated CSS easy to read, easy to test, and easy to drop into a design-token workflow. The control is not a perceptual interpolation setting, a noise field, or a true mesh surface — it is a single integer that controls how far each layer's color reaches before becoming transparent.
Building a Mesh Background Step by Step
- Open the Mesh Gradient Generator in your browser. The interface loads with default colors and a default spread so you have something to compare against as you tweak.
- Choose four mesh colors and one base color. The four mesh colors are the visible "blobs" in the result; the base color fills the empty regions and acts as a fallback if any layer fails to cover a corner of the element.
- Adjust the fade spread. The control runs from 10% to 90% in integer steps. Lower values keep each color compact and let the base color dominate between the circles. Higher values push each color further out and create softer, more blended regions near the centers.
- Watch the live CSS preview update as you change each input. The preview is painted with the exact declarations you will copy, so what you see is what the browser will render.
- Copy the complete background-color and background-image declarations from the output panel.
- Paste the declarations into a class, custom property, CSS module, or stylesheet that targets the element you want the background on. Add background-size, repeat, attachment, clipping, or animation properties separately only when the design actually needs them — the generator intentionally does not include them.
- Test the result in the real component: check text contrast, paint cost on representative hardware, and how the gradient looks across the browsers and color profiles your users actually run.
Choosing Colors and Tuning the Fade Spread
The fade spread is the single most powerful control in the layered approach, because it changes how the colors mix. A small spread leaves more of the base color visible and produces what looks like distinct color "islands." A larger spread lets the layers reach further, overlap more, and produce mixed tones in the middle of the element. Because the spread is integer-only, every value you try is reproducible in tests and in teammates' workflows.
| Spread value | Visual effect | Best for |
|---|---|---|
| 10 – 20% | Compact color islands with mostly visible base color between them | Bold, high-contrast backgrounds where the base color should read as the dominant surface |
| 30 – 50% | Balanced overlap with clear color identity in each region | Hero sections and feature panels where each color should still be recognizable |
| 60 – 80% | Heavy blending with soft mixed tones across most of the element | Atmospheric backgrounds that recede behind content |
| 90% | Maximum reach, strongest color saturation in the corners, mostly blended middle | Full-bleed backgrounds where the layered look is the main visual interest |
Pick a base color that sits well behind the four mesh colors. If the mesh colors are warm, a cool or neutral base prevents the result from feeling muddy. If you need the four colors to stay clearly separated, choose a base that contrasts with each of them and use a lower spread so the base shows through.
For production, lift the chosen colors into design tokens (CSS custom properties or your framework's token system) rather than pasting raw hex values everywhere. The generator validates six-digit hex input, so it will refuse anything outside that form, but downstream your own token system should still be the single source of truth. Document the intended foreground treatment next to each token so anyone reusing the gradient knows how text should sit on it.
Checking Contrast, Performance, and Cross-Browser Rendering
A mesh background is, by construction, a continuously varying surface. A foreground color that has acceptable contrast at one point of the element may not have acceptable contrast five hundred pixels away, because the underlying color mix shifts with each layer's spread and position. Test headings, body copy, links, focus indicators, and form controls across the entire background, not just at the center. If long passages of text need to sit on the mesh, consider a translucent surface layer or a simpler solid block behind the text rather than relying on the gradient alone.
Static layered gradients are usually lightweight because the browser only needs to paint four radial gradients once. The cost rises when you animate position, color, or size, or when the mesh element is unusually large, off-screen, or covered by expensive filters. Prefer a static background for normal page sections. If you do animate, measure paint and frame timing on representative mobile hardware, and respect prefers-reduced-motion by disabling the animation for users who request it. Avoid huge offscreen elements and excessive filter effects layered on top of the mesh.
CSS gradient syntax is standardized in the CSS Images Level 3 specification and documented in detail on MDN's radial-gradient reference, but the rendered pixels still vary between browsers, GPUs, color spaces, screenshots, and exported PDFs because of interpolation and color management. Always inspect the real target environment — emulators, design previews, and screenshots are not enough on their own. Force-colors and high-contrast modes should also be respected, and print styles should fall back to a solid or simpler treatment.
Because the generated background uses standard syntax, all calculation and copying happens in your current tab. No palette, CSS string, preview, or screenshot is uploaded, and the tool adds no runtime dependency. That makes it straightforward to use inside visual regression tests: capture the component at the sizes you ship and lock the rendered output so a future color change is intentional rather than accidental.
If you're weighing options, Box Shadow Generator Explained: Inside Each CSS Parameter covers this in detail.
If you're weighing options, How to Make Nice CSS Buttons With a Visual Workbench covers this in detail.