CSS Gradients: Linear, Radial and Conic, Explained
Design high-performance multi-stop linear, radial, and conic CSS gradients with real-time interactive previews and export clean CSS, Tailwind CSS arbitrary classes, and SVG defs in one click.
CSS Gradient Studio
100% In-browser execution. Zero server uploads, instant results, free forever.
Linear, Radial and Conic: Three Shapes of the Same Idea
CSS provides three gradient functions, and choosing correctly matters more than tuning colour stops.
`linear-gradient()` interpolates along a straight axis. The angle is specified in degrees where 0deg points up and values increase clockwise — so 90deg runs left to right and 180deg top to bottom. Keywords are often clearer: to bottom right adapts to the element's aspect ratio in a way a fixed angle does not.
`radial-gradient()` radiates outward from a point. Its syntax carries two independent ideas: shape (circle or ellipse) and size (closest-side, farthest-corner and others). farthest-corner is the default and produces a gradient reaching the most distant corner, which is usually what you want for a background wash.
background: radial-gradient(circle at 30% 20%, #6366f1, #0f172a 60%);
`conic-gradient()` sweeps around a centre point, like a clock hand. This is the function for pie charts, colour wheels and loading indicators, and it is frequently overlooked because it arrived later:
background: conic-gradient(#22c55e 0turn 0.3turn, #e5e7eb 0.3turn 1turn);
That single declaration is a 30% progress ring with no images and no JavaScript. Adding repeating- to any of the three tiles the gradient, which is how stripes and checks are made without assets.
Why Your Gradient Looks Grey in the Middle
A gradient from blue to yellow that passes through muddy grey is the most common gradient complaint, and it is a colour-space problem rather than a mistake in the stops.
By default CSS interpolates in sRGB, which is not perceptually uniform. Halfway between two saturated hues in sRGB often lands on a desaturated colour, because the shortest straight line between two points in that space passes through the low-saturation middle.
Modern CSS lets you choose the interpolation space, and oklab or oklch produce markedly better results because they are designed around perceptual uniformity:
background: linear-gradient(in oklab, #2563eb, #facc15);
For hue-based interpolation, oklch with a hue strategy travels around the colour wheel rather than across it:
background: linear-gradient(in oklch longer hue, #2563eb, #facc15);
The second recurring complaint is banding — visible steps rather than a smooth transition. It happens because 8-bit-per-channel colour offers only 256 levels, and a gradient spread across a wide area changes too slowly for each pixel row to differ. Three mitigations work: keep the colour distance shorter, overlay a very subtle noise texture to dither the transition, or add intermediate colour stops so the interpolation is recomputed more often.
Banding is most visible in dark gradients and in blues, where human vision is most sensitive to small luminance differences.
Colour Stops, Hard Edges and the Double-Stop Trick
A colour stop may carry a position, and two stops at the same position create a hard edge rather than a blend:
/* A crisp two-colour split, no transition */
background: linear-gradient(90deg, #ef4444 50%, #3b82f6 50%);
That technique builds stripes, progress bars and split backgrounds without images. The repeating- variants make it concise:
background: repeating-linear-gradient(
45deg, #f1f5f9 0 10px, #e2e8f0 10px 20px
);
Note the double-position syntax in that example — #f1f5f9 0 10px sets both the start and end position of a stop in one declaration, which is considerably clearer than repeating the colour.
Two further controls are underused:
Interpolation hints. A bare percentage between two stops moves the midpoint of the transition without adding a colour:
background: linear-gradient(#000, 30%, #fff);
Here the halfway colour occurs at 30% rather than 50%, which is useful for making an overlay fade feel natural rather than linear.
Transparency done correctly. Fading to transparent in sRGB interpolates toward transparent *black*, producing a grey haze against light backgrounds. Fade to an explicit transparent version of the same colour instead:
/* muddy */ linear-gradient(#3b82f6, transparent)
/* correct */ linear-gradient(#3b82f6, rgb(59 130 246 / 0))
Performance, Text Contrast and Reduced Motion
Gradients are painted, not composited, which has three practical consequences.
Animating gradient colour stops is expensive. Each frame repaints the entire gradient area on the main thread. The cheap way to animate a gradient is to render it larger than the element and animate background-position, or to cross-fade two stacked elements with opacity — both of which the compositor can handle.
Large gradients cost more than small ones, proportional to area. A full-viewport gradient behind a scrolling page is a common source of paint cost.
Text over a gradient has variable contrast. This is the accessibility issue, and it is the same shape as the one glass surfaces have: a heading that meets 4.5:1 over the dark end of a gradient may fall well below it over the light end. Check contrast at both extremes, not at the midpoint, and if the gradient must carry text, compress its luminance range so the worst case is known.
Respect reduced motion. Animated gradients — shifting hero backgrounds, moving meshes — should be static under prefers-reduced-motion: reduce. They are large-area movement, which is precisely the category that triggers vestibular symptoms.
Finally, background-clip: text makes gradient text, and it needs care: the element must have transparent text colour, and a fallback colour should be declared first so unsupported browsers show readable text rather than nothing:
.gradient-text {
color: #4f46e5; /* fallback, declared first */
background: linear-gradient(90deg, #4f46e5, #ec4899);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
The CSS gradient studio previews all three functions with live colour stops and copies the rule out. For surfaces that sit over a gradient, the glassmorphism generator pairs with it directly.
Frequently Asked Questions (FAQ)
What is the difference between linear, radial and conic gradients?
A linear gradient interpolates along a straight axis, with 0deg pointing up and values increasing clockwise. A radial gradient radiates outward from a point and takes a shape of circle or ellipse plus a size such as farthest-corner. A conic gradient sweeps around a centre point like a clock hand, which makes it the correct function for pie charts, colour wheels and progress rings.
Why does my gradient look grey in the middle?
Because CSS interpolates in sRGB by default, which is not perceptually uniform, so the straight line between two saturated hues passes through a desaturated middle. Specify a better interpolation space with syntax such as linear-gradient(in oklab, #2563eb, #facc15), or use in oklch longer hue to travel around the colour wheel rather than across it.
How do I fix banding in a CSS gradient?
Banding occurs because 8-bit colour offers only 256 levels per channel, so a gradient spread over a wide area changes too slowly for adjacent pixel rows to differ. Reduce the physical distance the gradient covers, add intermediate colour stops so interpolation is recomputed more often, or overlay a very subtle noise texture to dither the transition. It is most visible in dark gradients and in blues.
How do I create a hard edge in a gradient?
Place two colour stops at the same position, such as linear-gradient(90deg, #ef4444 50%, #3b82f6 50%), which produces a crisp split with no transition. The repeating- variants combined with double-position syntax, where a stop declares both its start and end such as #f1f5f9 0 10px, build stripes and checks without any image assets.
Why does fading to transparent produce a grey haze?
Because the transparent keyword is transparent black, so interpolating toward it in sRGB passes through progressively darker semi-transparent greys. Fade to an explicit transparent version of the same colour instead, such as rgb(59 130 246 / 0) rather than the transparent keyword.
Are CSS gradients bad for performance?
They are painted rather than composited, so cost scales with the area covered and animating colour stops repaints the whole area on the main thread every frame. Animate background-position on an oversized gradient, or cross-fade two stacked elements with opacity, since both of those the compositor can handle. Animated gradients should also be made static under prefers-reduced-motion.
Related Guides & Solutions
Frosted Glass UI in Pure CSS (Glassmorphism)
Neumorphism in CSS: Soft UI Shadows That Work
Smooth CSS Keyframe Animations Without a Library
Bold and Italic Text for LinkedIn and X Posts
Ready to use CSS Gradient Studio?
Execute this workflow privately on your device right now without creating an account or paying for cloud API credits.