A CSS mesh gradient is made by layering four radial-gradient() color fields over one base background color.

Each circle starts with a solid color at its focal point and fades to transparent, allowing the overlapping fields to create a soft mesh-style blend. This is an approximation of a graphic-design mesh, not a native mathematical mesh surface. MDN’s radial-gradient() reference and the CSS Images Level 3 specification explain the standard syntax behind the effect.

how to make mesh gradient in css
How to Make Mesh Gradients in CSS with Four Layers

The four-layer background model

The gradient list uses comma-separated layers, and the first listed gradient appears closest to the viewer. Four fixed focal positions keep the composition predictable: two fields sit near the top of the element and two sit near the bottom.

Paint order Focal position Role
1 15% 20% First listed gradient, closest to the viewer
2 85% 15% Second listed gradient
3 20% 85% Third listed gradient
4 80% 80% Fourth listed gradient

The base color sits behind all four images. It fills regions where every gradient is transparent and provides a predictable fallback when the gradient layers do not cover the complete element. Because the background consists entirely of CSS gradients, it can scale with its container without adding an image request.

At a 60% fade spread, an illustrative four-layer declaration has this structure:

  • background-color: #18152B;
  • background-image: radial-gradient(circle at 15% 20%, #6C5CE7 0%, transparent 60%), radial-gradient(circle at 85% 15%, #18C7C8 0%, transparent 60%), radial-gradient(circle at 20% 85%, #FF5C8A 0%, transparent 60%), radial-gradient(circle at 80% 80%, #F7B84B 0%, transparent 60%);

The colors in this example are illustrative, but the structure is the same: an explicit circle, a fixed position, a color stop at 0%, and a transparent terminal stop at the selected spread.

Build the gradient in five steps

  1. Choose four mesh colors and a base color. Open the Mesh Gradient Generator’s four-color workflow. Select four colors for the radial fields and one background color for the area beneath them. The tool validates all five values as six-digit hexadecimal colors before generating the preview.
  2. Set the fade spread. Choose an integer from 10% through 90%. A lower value keeps each color in a compact area and exposes more of the base color. A higher value carries each color across a larger portion of the element, creating broader overlaps and softer mixed regions.
  3. Inspect the live preview. Check the corners, center, and every area that will contain text or controls. The preview uses the exact declarations shown in the output, so it is a reliable preview of the generated CSS structure rather than a separate rendering.
  4. Copy the complete background declarations. Copy both the background-color and background-image declarations. Preserve the gradient order because the first layer is closest to the viewer.
  5. Integrate and test the result. Paste the declarations into a class, custom-property workflow, CSS module, or stylesheet. Then test contrast, paint cost, and cross-browser rendering in the actual component rather than judging only the isolated preview.

All calculations and copying happen in the current tab. The generator does not upload or save your palette, CSS, preview, or screenshot, and the generated background requires no external asset.

Tune the fade spread

The spread controls how far each selected color remains visible before reaching transparency. At the lower end of 10%, the four fields behave more like compact islands, with visible gaps of base color between them. As the value increases toward 90%, the fields cover more of the element and overlap across a larger area. This creates a softer mesh-style composition without relying on blur filters.

Spread is not a physical blur radius, perceptual interpolation setting, noise field, or true mesh surface. Its control is deliberately limited to integer percentages so the copied CSS remains understandable and testable. The generator also uses fixed focal positions rather than allowing the four anchors to be dragged freely.

Even when every browser receives identical declarations, browser color interpolation and display profiles can affect the perceived blend. Treat the preview as a design guide, then confirm the result in the browsers, devices, and color settings used by your audience.

Apply the output in a real component

For a direct implementation, paste the copied background-color and background-image declarations into the rule that owns the section, card, or hero element. If your project uses custom properties, CSS modules, or a centralized stylesheet, place them in the corresponding workflow without changing the layer order.

Add background-size, repeat, attachment, clipping, or animation rules separately, and only when the design requires them. These properties can alter the composition, so adding them reflexively may move the focal points or change the intended coverage.

A static mesh-style background works well for many page sections because it scales without an image request. For an interactive treatment, keep the gradient structure intact and treat movement as an enhancement rather than a requirement.

Make text readable over every region

A mesh gradient can create locally bright and dark areas, so one foreground color may be readable in one section but fail in another. A visually attractive background does not guarantee adequate text contrast, especially across headings, body copy, links, focus indicators, and form controls.

The Mesh Gradient Generator does not calculate WCAG contrast because its background varies continuously by position. Test the complete foreground treatment across the whole gradient rather than checking only the center. For long passages, consider placing the text over a translucent surface or using a simpler solid section behind it.

Also check how the component behaves in forced-colors and high-contrast modes, and confirm that it remains legible in print styles. If the background or its colors move, honor reduced-motion preferences rather than treating motion as a required part of the design.

Test rendering and paint cost

Cross-browser appearance

The generated syntax is standard CSS, but interpolation, color management, GPU rendering, screenshots, and exported PDFs can produce small visual differences. Inspect the component in the actual target environments rather than assuming that identical code will produce identical pixels everywhere.

Performance and motion

Layered gradients are usually lightweight, but large animated backgrounds or frequent style changes can increase paint cost and power consumption. Prefer a static background for normal page sections. If positions or colors are animated, measure the result on representative mobile hardware and honor prefers-reduced-motion. Avoid unnecessarily large offscreen elements and excessive filter effects.

Make the gradient maintainable

For a design system, move the final colors into named tokens instead of scattering unexplained hexadecimal values across components. Document the intended foreground treatment, including any translucent panel or solid section used to protect text readability.

Add visual regression coverage at the component sizes you ship. A compact preview cannot reveal every contrast, overlap, or rendering issue that appears when the gradient stretches across a real page, so production checks remain part of the workflow rather than an optional extra.