BytePane

CSS Gradient Generator: Create Beautiful Gradients

CSS19 min read

Key Takeaways

  • No vendor prefixes needed in 2026 — linear-gradient() and radial-gradient() are universally supported. Conic gradients hit 96%+ coverage.
  • The gray dead-zone problem in blue→yellow gradients is fixed with in oklch interpolation — CSS Color Level 4, ~93% support.
  • CSS gradients are GPU-accelerated — replacing decorative gradient PNGs with CSS eliminates HTTP requests with zero visual quality loss.
  • Per WebAIM's 2025 accessibility report, 79.1% of websites fail WCAG color contrast. Gradients make this worse — test contrast at the lightest gradient point.
  • Tailwind CSS v4 defaults to OKLCH for its color palette — mesh and "liquid glass" gradients are the dominant 2026 design trend.

Consider this data point: conic gradients — the most recently standardized gradient type — now have 96%+ global browser support per caniuse.com data in 2026. Yet most developers only reach for linear-gradient. Meanwhile, Tailwind CSS v4, released in 2025, switched its entire color palette from HSL to OKLCH — a move that changes how gradients look at every color stop.

This guide covers the full CSS gradient toolkit: syntax, color stop mechanics, the OKLCH interpolation upgrade, performance characteristics, and accessibility requirements. At the end, you will know not just how to write gradients, but why they look the way they do — and how to fix them when they do not.

Linear Gradients: Full Syntax Reference

linear-gradient() is defined in CSS Images Level 3. The formal syntax is:

/* Direction variants */
background: linear-gradient(to right, #6366f1, #8b5cf6);    /* keyword */
background: linear-gradient(90deg, #6366f1, #8b5cf6);       /* angle (equivalent) */
background: linear-gradient(to bottom left, #6366f1, #8b5cf6); /* diagonal */
background: linear-gradient(135deg, #6366f1, #8b5cf6);      /* same diagonal */

/* Multiple color stops with explicit positions */
background: linear-gradient(
  to right,
  #1a1a2e 0%,      /* dark navy at 0% */
  #6366f1 40%,     /* indigo at 40% */
  #8b5cf6 70%,     /* purple at 70% */
  #ec4899 100%     /* pink at 100% */
);

/* Color hint (midpoint shift) */
background: linear-gradient(to right, #6366f1 20%, #8b5cf6);
/* ^ the 20% hint shifts the midpoint — more indigo coverage */

/* Hard stop (no transition) */
background: linear-gradient(
  to right,
  #6366f1 50%,
  #8b5cf6 50%   /* same position = hard edge */
);

/* Repeated pattern */
background: repeating-linear-gradient(
  45deg,
  #6366f1,
  #6366f1 10px,
  #1a1a2e 10px,
  #1a1a2e 20px
);

Angle Reference

KeywordAngleDirection
to top0degBottom → Top
to right90degLeft → Right
to bottom180degTop → Bottom (default)
to left270degRight → Left
to bottom right~135degTop-left → Bottom-right (adjusted for element size)

Radial Gradients: Centers, Shapes, and Sizes

radial-gradient() spreads outward from a center point. You control the shape (circle or ellipse), size, and position:

/* Default: ellipse at center */
background: radial-gradient(#6366f1, #1a1a2e);

/* Explicit circle */
background: radial-gradient(circle, #6366f1 0%, #1a1a2e 70%);

/* Circle at specific position */
background: radial-gradient(circle at 30% 70%, #8b5cf6, transparent);

/* Size keywords */
background: radial-gradient(closest-side circle at 25% 25%, #6366f1, transparent);
background: radial-gradient(farthest-corner circle, #6366f1, #1a1a2e);

/* Glassmorphism glow effect: stack multiple radials */
background:
  radial-gradient(ellipse at 20% 80%, rgba(99, 102, 241, 0.4) 0%, transparent 50%),
  radial-gradient(ellipse at 80% 20%, rgba(139, 92, 246, 0.4) 0%, transparent 50%),
  radial-gradient(ellipse at 50% 50%, rgba(236, 72, 153, 0.2) 0%, transparent 70%),
  #0f0f1a;

/* Spotlight text effect */
.hero {
  background:
    radial-gradient(ellipse 80% 40% at 50% 60%, rgba(99, 102, 241, 0.3), transparent),
    #0a0a0f;
}

Conic Gradients: The Underused Power Tool

conic-gradient() transitions around a center point (like a pie chart rotation rather than a radial spread). According to caniuse.com, conic gradients reached 96.2% global browser support in 2026 — well past the threshold for production use without fallbacks.

/* Basic conic (pie chart pattern) */
background: conic-gradient(#6366f1 0%, #8b5cf6 33%, #ec4899 66%, #6366f1 100%);

/* Pie chart: 40% indigo, 35% purple, 25% pink */
background: conic-gradient(
  #6366f1 0deg 144deg,    /* 40% of 360 = 144deg */
  #8b5cf6 144deg 270deg,  /* 35% of 360 = 126deg */
  #ec4899 270deg 360deg   /* 25% of 360 = 90deg */
);

/* Starting angle offset */
background: conic-gradient(from 90deg, #6366f1, #8b5cf6, #ec4899, #6366f1);

/* Color wheel */
background: conic-gradient(
  red, yellow, lime, cyan, blue, magenta, red
);

/* Checkerboard pattern using conic */
background:
  conic-gradient(#1a1a2e 90deg, transparent 90deg) 0 0 / 40px 40px,
  conic-gradient(transparent 270deg, #1a1a2e 270deg) 20px 20px / 40px 40px;

/* Donut chart with clip-path */
.donut {
  width: 200px; height: 200px; border-radius: 50%;
  background: conic-gradient(#6366f1 0deg 180deg, #8b5cf6 180deg);
  -webkit-mask: radial-gradient(circle, transparent 60px, black 60px);
  mask: radial-gradient(circle, transparent 60px, black 60px);
}

The checkerboard pattern is a good example of a pattern that previously required an SVG background or a CSS hack with background-size tricks — now a single conic-gradient handles it.

Fixing the Gray Dead Zone with OKLCH Interpolation

Here is the most common complaint about CSS gradients: "my blue-to-yellow gradient looks muddy in the middle." This is not a bug — it is CSS working as specified. By default, gradients interpolate in sRGB, where complementary colors converge toward a neutral gray at the 50% midpoint.

CSS Color Level 4 (supported in Chrome 111+, Firefox 113+, Safari 16.2+) introduced the color-interpolation-method keyword: in oklch. OKLCH (Oklab Lightness Chroma Hue) is a perceptually uniform color space where equal numerical steps produce equal-looking changes. The midpoint of blue→yellow in OKLCH is a vivid green, not a gray sludge.

/* sRGB interpolation (default) — muddy gray midpoint */
background: linear-gradient(to right, blue, yellow);

/* OKLCH interpolation — vivid green midpoint */
background: linear-gradient(in oklch to right, blue, yellow);

/* With explicit OKLCH color values */
background: linear-gradient(
  in oklch to right,
  oklch(50% 0.25 264),   /* blue in OKLCH */
  oklch(85% 0.20 95)     /* yellow in OKLCH */
);

/* Shorter hue path (through warm colors) vs longer (through cool) */
background: linear-gradient(in oklch shorter hue to right, blue, red);
background: linear-gradient(in oklch longer hue to right, blue, red);

/* Other useful interpolation spaces */
background: linear-gradient(in lab to right, blue, yellow);      /* perceptual, no hue rotation */
background: linear-gradient(in display-p3 to right, blue, yellow); /* wide gamut displays */

/* Progressive enhancement: fallback for older browsers */
.hero-bg {
  background: linear-gradient(to right, #3b82f6, #eab308);  /* sRGB fallback */
  background: linear-gradient(in oklch to right, #3b82f6, #eab308); /* overrides if supported */
}

Tailwind CSS v4's switch to OKLCH as the default palette color space means that Tailwind gradient utilities like bg-gradient-to-r from-blue-500 to-yellow-400 automatically use OKLCH interpolation in browsers that support it.

Mesh Gradients and Multi-Layer Backgrounds

Mesh gradients — the multi-directional, organic color blends that dominated UI design starting in 2024 — cannot be perfectly replicated in pure CSS. What you can do is stack multiple radial gradients with rgba() transparency to approximate the effect. The CSS background shorthand accepts comma-separated layers, rendered back-to-front.

/* CSS mesh gradient approximation — 4 stacked radials */
.mesh-bg {
  background-color: #0f0f1a;  /* base color */
  background-image:
    radial-gradient(ellipse 60% 50% at 15% 20%, oklch(55% 0.20 280 / 0.6), transparent),
    radial-gradient(ellipse 55% 45% at 85% 15%, oklch(55% 0.22 310 / 0.5), transparent),
    radial-gradient(ellipse 70% 60% at 75% 85%, oklch(60% 0.18 240 / 0.55), transparent),
    radial-gradient(ellipse 50% 55% at 25% 80%, oklch(70% 0.15 160 / 0.4), transparent);
}

/* Animated mesh gradient (GPU-accelerated via filter: hue-rotate) */
@keyframes mesh-rotate {
  to { filter: hue-rotate(360deg); }
}

.animated-mesh {
  background-color: #0f0f1a;
  background-image:
    radial-gradient(ellipse 60% 50% at 15% 20%, #6366f1aa, transparent),
    radial-gradient(ellipse 55% 45% at 85% 15%, #8b5cf6aa, transparent),
    radial-gradient(ellipse 70% 60% at 75% 85%, #3b82f6aa, transparent);
  animation: mesh-rotate 10s linear infinite;
}

/* Noise texture overlay for grainy gradient (trendy in 2026) */
.grainy-gradient {
  background: linear-gradient(135deg, #6366f1, #8b5cf6);
  position: relative;
}

.grainy-gradient::after {
  content: '';
  position: absolute; inset: 0;
  background-image: url("data:image/svg+xml,..."); /* SVG feTurbulence noise */
  opacity: 0.05;
  pointer-events: none;
}

Gradient Comparison

TypeBrowser SupportBest ForRepeating?
linear-gradient99%+Buttons, hero overlays, directional backgroundsYes
radial-gradient99%+Glows, spotlights, vignettes, pulsing effectsYes
conic-gradient96.2%Pie charts, color wheels, checkerboards, spinnersYes
in oklch interpolation93%Vivid multi-hue transitions without gray midpointsYes
Mesh (SVG/Canvas)100%Complex organic color blends (requires non-CSS techniques)N/A

Practical Gradient Patterns

These are patterns you will reach for repeatedly in real interfaces:

Image Overlay for Readable Text

/* Hero section: image with text readability overlay */
.hero {
  background:
    linear-gradient(
      to bottom,
      transparent 0%,
      transparent 30%,
      rgba(0, 0, 0, 0.7) 70%,
      rgba(0, 0, 0, 0.9) 100%
    ),
    url('/hero.jpg') center / cover no-repeat;
  min-height: 100vh;
}

/* Card image fade to background color */
.card-image {
  background:
    linear-gradient(to bottom, transparent 50%, var(--card-bg) 100%),
    url('/card.jpg') center / cover;
  height: 200px;
}

Button Shine Effect

/* Glossy button with shine highlight */
.btn-gradient {
  background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
  position: relative;
  overflow: hidden;
}

.btn-gradient::before {
  content: '';
  position: absolute;
  top: 0; left: -100%; right: 100%; bottom: 0;
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(255, 255, 255, 0.15) 50%,
    transparent 100%
  );
  transition: left 0.4s ease, right 0.4s ease;
}

.btn-gradient:hover::before {
  left: 100%; right: -100%;  /* swipe shine across button on hover */
}

Border Gradient (Gradient-Outline Trick)

/* Gradient border using background-clip */
.gradient-border {
  background:
    linear-gradient(#0f0f1a, #0f0f1a) padding-box,  /* fill inside */
    linear-gradient(135deg, #6366f1, #ec4899) border-box;  /* gradient border */
  border: 2px solid transparent;
  border-radius: 12px;
}

/* Works in all modern browsers. For IE/legacy support, use ::before pseudo-element instead. */

/* Animated gradient border */
@keyframes border-rotate {
  to { --angle: 360deg; }
}

@property --angle {
  syntax: '<angle>';
  initial-value: 0deg;
  inherits: false;
}

.animated-border {
  background:
    linear-gradient(#0f0f1a, #0f0f1a) padding-box,
    conic-gradient(from var(--angle), #6366f1, #8b5cf6, #ec4899, #6366f1) border-box;
  border: 2px solid transparent;
  border-radius: 12px;
  animation: border-rotate 4s linear infinite;
}

Accessibility: Gradients and Contrast

According to WebAIM's 2025 Million accessibility report, 79.1% of websites fail WCAG color contrast requirements — making contrast errors the single most common accessibility failure for the sixth consecutive year. Gradients compound this problem because contrast is not uniform across the element.

WCAG 2.1 AA requires:

  • 4.5:1 contrast ratio for normal text (below 18pt or 14pt bold)
  • 3:1 contrast ratio for large text (18pt+ / 14pt+ bold)
  • 3:1 for non-text UI components (icons, borders on interactive elements)
/* ❌ Problematic: white text over a light-to-dark gradient */
.card {
  background: linear-gradient(to bottom, #ffffff, #333333);
  color: white;  /* passes at 100% (7:1) but fails at 0% (1:1 vs white bg) */
}

/* ✅ Fix option 1: dark background always under text */
.card {
  background:
    linear-gradient(to bottom, transparent 0%, rgba(0,0,0,0.85) 50%),
    url('/image.jpg') center / cover;
  /* Text is always over the dark portion */
}

/* ✅ Fix option 2: test contrast at lightest gradient point */
/* For linear-gradient(to right, #6366f1, #8b5cf6) with white text: */
/* #6366f1 → contrast ratio with white = 3.82:1 (AA fail for small text) */
/* Use APCA or WCAG checker at the lightest stop */

/* ✅ Fix option 3: text shadow for mixed-background readability */
.hero-text {
  text-shadow: 0 1px 4px rgba(0,0,0,0.6);  /* adds contrast on any background */
}

Use BytePane's Color Picker to check contrast ratios between your text and gradient color stops. The color converter tool shows WCAG pass/fail at each stop so you can catch failures before shipping.

Performance: CSS Gradients vs Images

CSS gradients are rendered on the GPU — they are effectively free from a performance standpoint once the initial style calculation is done. Compared to serving a gradient as a PNG:

MetricCSS GradientPNG Image (1200×630)
Transfer size~100 bytes50–150 KB
HTTP requests01
Decode time0ms2–10ms
Memory (VRAM)~0Width × Height × 4 bytes
Scale qualityPerfect at any sizeBlurs on upscale
AnimationLimited (filter: hue-rotate)Not practical

The one performance caveat: very complex multi-layer gradients with many stops on mobile can cause paint time regressions. A mesh gradient built from 8+ radial layers can trigger expensive compositing on GPU-limited devices. If you measure LCP or INP regressions after adding complex gradients, simplify the gradient or replace it with a pre-rendered image for the above-the-fold section.

Another consideration: animating gradients directly (transitioning gradient stop positions or colors) forces a repaint on every frame. The recommended approach is to animate only GPU-composited properties like transform, opacity, or filter: hue-rotate() on the gradient element rather than transitioning the gradient definition itself.

CSS Custom Properties and Design Tokens

Combining gradients with CSS custom properties enables design systems where gradients are theming primitives — swap one variable to change every gradient in your UI simultaneously.

:root {
  --gradient-primary: linear-gradient(135deg, #6366f1, #8b5cf6);
  --gradient-hero: linear-gradient(
    in oklch 135deg,
    oklch(55% 0.20 280),
    oklch(55% 0.22 310)
  );
  --gradient-cta: linear-gradient(90deg, #6366f1 0%, #ec4899 100%);

  /* Individual color tokens for gradients */
  --color-gradient-start: #6366f1;
  --color-gradient-end: #8b5cf6;
}

/* Theming: swap the gradient in one place */
[data-theme="dark"] {
  --color-gradient-start: #4f46e5;
  --color-gradient-end: #7c3aed;
}

/* Use in components */
.hero-section {
  background: var(--gradient-hero);
}

.cta-button {
  background: var(--gradient-cta);
}

/* @property enables smooth CSS variable transitions (Houdini) */
@property --gradient-angle {
  syntax: '<angle>';
  initial-value: 135deg;
  inherits: false;
}

.rotating-gradient {
  background: linear-gradient(var(--gradient-angle), #6366f1, #ec4899);
  transition: --gradient-angle 0.3s ease; /* animates smoothly! */
}

.rotating-gradient:hover {
  --gradient-angle: 315deg;
}

Frequently Asked Questions

What is the CSS syntax for a linear gradient?
background: linear-gradient(direction, color-stop1, color-stop2). Direction can be an angle (45deg, 180deg) or keyword (to right, to bottom left). No vendor prefixes are needed in 2026 — all modern browsers support the unprefixed syntax.
What is the difference between linear-gradient and radial-gradient?
linear-gradient transitions along a straight line. radial-gradient radiates outward from a center point in elliptical or circular shapes. Use linear for directional swooshes and hero overlays; use radial for spotlight effects and glassmorphism glows.
Are CSS gradients supported in all browsers?
Linear and radial gradients have had universal support since 2013. Conic gradients reached 96.2% global browser support in 2026. OKLCH interpolation (in oklch keyword) has ~93% support. No vendor prefixes are needed for any gradient type.
How do I add readable text over a gradient background?
WCAG 2.1 AA requires 4.5:1 contrast for normal text. Test contrast at the lightest gradient stop — that is the worst case. Add a semi-transparent dark overlay for hero text: background: linear-gradient(rgba(0,0,0,0), rgba(0,0,0,0.7)), url(image.jpg). Per WebAIM 2025, 79.1% of websites fail contrast requirements.
Why do CSS gradients look washed out in the middle?
The "gray dead zone" is caused by sRGB interpolation: complementary colors pass through a gray midpoint. Fix it with OKLCH interpolation: linear-gradient(in oklch to right, blue, yellow). OKLCH is perceptually uniform — the midpoint is a vivid color, not gray.
Do CSS gradients affect page performance?
CSS gradients are GPU-accelerated with zero HTTP requests, zero decode time, and perfect scalability. Replacing a decorative gradient PNG (50-150KB) with CSS saves a full HTTP request. The only caveat: very complex multi-layer gradients on GPU-limited mobile devices can cause paint regressions.
What is a mesh gradient and how do I make one in CSS?
A mesh gradient blends multiple color points non-linearly. Pure CSS approximates it with stacked radial-gradient layers using rgba transparency. True mesh gradients require SVG feBlend filters or Canvas. Animated mesh gradients can use filter: hue-rotate() on the stacked radials for GPU-safe animation.

Generate CSS Gradients Visually

Use BytePane's CSS Gradient Generator to build linear, radial, and conic gradients visually and copy the CSS output instantly. Color picker and OKLCH color picker included.

Related Articles