CSS Gradient Generator: Create Beautiful Gradients
Key Takeaways
- ▸No vendor prefixes needed in 2026 —
linear-gradient()andradial-gradient()are universally supported. Conic gradients hit 96%+ coverage. - ▸The gray dead-zone problem in blue→yellow gradients is fixed with
in oklchinterpolation — 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
| Keyword | Angle | Direction |
|---|---|---|
| to top | 0deg | Bottom → Top |
| to right | 90deg | Left → Right |
| to bottom | 180deg | Top → Bottom (default) |
| to left | 270deg | Right → Left |
| to bottom right | ~135deg | Top-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
| Type | Browser Support | Best For | Repeating? |
|---|---|---|---|
| linear-gradient | 99%+ | Buttons, hero overlays, directional backgrounds | Yes |
| radial-gradient | 99%+ | Glows, spotlights, vignettes, pulsing effects | Yes |
| conic-gradient | 96.2% | Pie charts, color wheels, checkerboards, spinners | Yes |
| in oklch interpolation | 93% | Vivid multi-hue transitions without gray midpoints | Yes |
| 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:
| Metric | CSS Gradient | PNG Image (1200×630) |
|---|---|---|
| Transfer size | ~100 bytes | 50–150 KB |
| HTTP requests | 0 | 1 |
| Decode time | 0ms | 2–10ms |
| Memory (VRAM) | ~0 | Width × Height × 4 bytes |
| Scale quality | Perfect at any size | Blurs on upscale |
| Animation | Limited (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?
What is the difference between linear-gradient and radial-gradient?
Are CSS gradients supported in all browsers?
How do I add readable text over a gradient background?
Why do CSS gradients look washed out in the middle?
Do CSS gradients affect page performance?
What is a mesh gradient and how do I make one in CSS?
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.