CSS Gradient Generator

CSS Gradient Generator

Create beautiful linear, radial, conic CSS gradients visually. Copy CSS code instantly. Free online gradient maker with multiple color stops

A linear gradient between two colors looks fine until you put it in production and it shows ugly gray bands across the middle — the classic "gradient through gray" problem caused by interpolating in sRGB instead of a perceptually-uniform color space. This builder lets you author linear, radial, and conic gradients visually; previews them in modern OKLCH interpolation (new in CSS Color Module 4, supported by Chrome 111+, Safari 16.4+); and outputs both the legacy `linear-gradient(...)` and the modern `linear-gradient(in oklch, ...)` syntaxes.

Three gradient types, three use cases

  • linear-gradient — colors transition along a line. Specify angle (0deg = bottom-to-top, 90deg = left-to-right, "to top right" etc.) and color stops. The default for backgrounds, headers, hero sections.
  • radial-gradient — colors radiate from a center. Specify shape (circle/ellipse), size, and position. Spotlight effects, button highlights, soft edges.
  • conic-gradient — colors sweep around a center point like a clock. Pie charts, color wheels, donut charts purely in CSS (Lea Verou's most-cited demo). Supported everywhere since Firefox 83 (Nov 2020).

The "muddy gray middle" problem and how to fix it

Input

linear-gradient(90deg, #0000FF, #FFFF00)

Output

Default sRGB interpolation:
  Blue → desaturated gray → yellow
  Midpoint looks like dirty olive.

Modern OKLCH interpolation:
  linear-gradient(in oklch, #0000FF, #FFFF00)
  Blue → vivid magenta → orange → yellow
  Midpoint stays saturated.

Why: sRGB interpolation averages RGB channels linearly, which means at the midpoint of
blue (#0000FF) and yellow (#FFFF00) you get #808080 — gray. Perceptual color spaces like
OKLCH average in lightness/chroma/hue, preserving saturation along the path.

For any gradient between two highly-saturated colors of different hues, use `in oklch` or `in oklch longer hue` for the rainbow path. For grayscale gradients (white→black, dark→darker) sRGB is fine.

Color stops and positioning rules

  • Color stops can be unpositioned (evenly distributed) or positioned (`red 0%, yellow 60%, green 100%`). Unpositioned: equal spacing. Positioned: explicit %.
  • Hard stops — duplicate a position to create a sharp transition: `red 50%, blue 50%`. Looks like a two-color stripe, not a gradient. Useful for split backgrounds.
  • Hint points — single percentage between two color stops shifts the midpoint of the transition: `red, 30%, blue` makes the midpoint at 30% instead of 50%. Subtle but useful for non-linear feels.
  • Negative and over-100% positions — `red -20%, blue 120%` extends the gradient beyond the visible area. Lets you visually crop the "interesting" middle of a gradient.
  • "to" keyword vs angle — `to bottom right` is direction-relative (works regardless of element shape); `135deg` is absolute. Prefer "to" for layouts that may flip in RTL contexts.

Performance and rendering gotchas

  • Gradients are GPU-accelerated as backgrounds on modern browsers, but expensive to compose if redrawn every frame. Animating gradient stops via custom properties triggers re-rasterization — prefer animating opacity or position of a fixed gradient overlay.
  • Multiple gradients in one background — `background: linear-gradient(...), linear-gradient(...), url(...)` layers them. First in source = topmost in stack. Cheaper than multiple stacked elements for static layouts.
  • Diagonal gradients (`45deg`) can show banding on low-end displays. Either accept the banding, dither with a subtle noise overlay, or use a 24-bit lossless image instead of CSS.
  • Conic gradients on iOS Safari were slow up to ~16.0; perf has improved but complex animated conics still drop frames. Test on actual mobile, not just devtools.

When to reach for this tool

  • You are designing a hero section background and want to compare several gradient options visually before committing.
  • You inherited a "muddy" gradient in production and want to convert it to OKLCH interpolation without changing the visible color story.
  • You are building a charting library and need conic gradients for pie/donut visuals.
  • You want a meshed background of overlapping gradients (like the Stripe homepage style) and need help layering them.

What this tool will not do

  • It will not generate fallbacks for ancient browsers (IE 11). Linear gradients have been universal since 2013; if you support pre-2015 browsers, add a flat-color fallback manually.
  • It will not export to images. CSS gradients are vector-like — they scale, they re-render at device pixel density, and they are far smaller than the equivalent PNG. Export to image only if you specifically need a raster (email templates that strip background CSS).
  • It will not check WCAG contrast of text over the gradient. The contrast varies pixel by pixel along the gradient. For text overlays, set an opacity overlay or use the worst-case point.

Frequently asked questions

What is the difference between OKLCH and HSL for gradients?

HSL (1978) is computationally cheap and intuitive but perceptually wrong — equal HSL distances do not look like equal visual distances. OKLCH (2020) is perceptually uniform — interpolation in OKLCH produces gradients that look smooth to the eye. For new code, prefer OKLCH; HSL is fine for non-gradient color picking where the perceptual issue does not show up.

Can I animate a gradient in CSS?

Not the gradient itself (CSS does not interpolate `background-image: linear-gradient(...)` between values). Workarounds: animate the gradient angle via custom properties + `@property` registration; animate the background-position of an oversized gradient; or stack two gradient layers and cross-fade them with opacity. The last is the cheapest.

Why does my gradient look different on iPhone vs Mac?

Display color gamuts differ. Most modern iPhones and Macs are wide-gamut (P3); older displays are sRGB. If you specify colors in `display-p3(...)`, they look correct on wide-gamut and clamp to sRGB on standard displays. If you specify in #hex (assumed sRGB), they are accurate on sRGB and may look slightly desaturated on P3 displays.

How do I make a gradient that ends in transparency?

Use rgba/oklch with alpha 0: `linear-gradient(to bottom, black, oklch(0% 0 0 / 0))`. Important: do NOT use `linear-gradient(to bottom, black, transparent)` — `transparent` in CSS is `rgba(0,0,0,0)`, so the gradient interpolates through gray-black-with-zero-alpha at the midpoint. Use the actual color with alpha 0.

Why does my radial gradient look elliptical when I wanted a circle?

Default shape is `ellipse`, sized to the container. Explicit: `radial-gradient(circle at center, red, blue)`. Add `closest-side`/`farthest-corner` for sizing: `radial-gradient(circle closest-side, ...)` makes the gradient end at the nearest edge.

Are gradients accessible?

Background gradients are decorative; screen readers ignore them. The accessibility question is text contrast over the gradient — see "color contrast over gradient" in the color-analyzer tool. For functional gradients (a temperature scale on a heat map), pair with text labels and a discrete colorblind-safe alternative.

Related tools

Last updated · E-Utils editorial team