The CSS Gradient Guide: Linear, Radial, and Conic Without the Mud
Learn when to use linear, radial, and conic CSS gradients, how color stop positions work, and the one trick that keeps your gradients from going gray in the middle.
The CSS Gradient Guide: Linear, Radial, and Conic Without the Mud
A flat background color is a decision you make in a hurry. A good gradient is a decision you make on purpose. The gap between the two is mostly knowledge: which gradient type to reach for, where to drop your color stops, and why some pairs of colors turn to mud in the middle while others glow.
This guide walks through all three CSS gradient types, the color-stop mechanics that nobody explains, and a midpoint trick that quietly fixes the ugliest gradient problem of all. You can follow along in the CSS Gradient Generator, which builds the exact background: value as you tweak.
Three gradient types, three jobs
CSS gives you three gradient functions, and each one answers a different question.
A linear gradient fades along a straight line. You pick an angle, and the color marches from one edge to the other. This is the workhorse: hero backgrounds, button fills, dividers, anything with a sense of direction. 0deg goes bottom to top, 90deg goes left to right, 135deg runs diagonally down — the classic "designer default" you see on half the SaaS sites on the internet.
A radial gradient fades outward from a point, like a spotlight. Instead of a direction, you choose a shape (circle or ellipse) and an anchor (center, or one of the corners). Use it for glow halos, card-corner highlights, faux-3D spheres, and the soft ambient light that makes glassmorphism cards look like they sit above the page instead of flat against it.
A conic gradient sweeps around a point like a clock hand. The color rotates through the angles rather than fading across a distance. This is your tool for pie-chart slices, color wheels, loading spinners, and the glossy-disc sheen on app icons.
The shortcut: want a fade, use linear; want a light source, use radial; want rotation, use conic.
How color stops actually work
A gradient is a list of color stops, and each stop can carry an explicit position from 0% to 100%. This is where most gradients are won or lost.
The CSS gradient syntax is defined in the CSS Images Module Level 3 on MDN, and the rule is simple: a stop written as red 30% plants that color at the 30% mark along the gradient line. If you omit positions, the browser spaces stops evenly — two stops land at 0% and 100%, three stops at 0%, 50%, 100%, and so on.
The power is in moving stops off the even grid. Push two colors close together (say 40% and 45%) and you get a sharp transition — almost a hard edge. Spread them apart and the blend gets lazy and soft. A "hard stop" — two stops at the same position like blue 50%, green 50% — gives you a crisp two-tone split with no blending at all, which is how you fake stripes and color blocks.
So a color stop position is not decoration. It is the dial that controls whether your gradient feels tense or relaxed, sharp or dreamy.
A real two-color example
Let me walk through one concretely. Say I'm building a hero and I want an indigo-to-violet diagonal. I open the generator, set the type to linear, drag the angle dial to 135°, and pick two stops: #4f46e5 (indigo-600) at 0% and #8b5cf6 (violet-500) at 100%. The output panel hands me this:
background: linear-gradient(135deg, #4f46e5 0%, #8b5cf6 100%);
That single line drops straight into a stylesheet rule, a styled-component template literal, or a React style={{ background: '...' }} prop. For Tailwind, the same value goes behind an arbitrary class like bg-[linear-gradient(135deg,#4f46e5_0%,#8b5cf6_100%)]. Browser support is universal for linear and radial; conic landed in Chrome 69+, Safari 12.1+, and Firefox 83+, so it's safe everywhere modern.
The first time I did this for a side project, I spent twenty minutes nudging the angle by single degrees, convinced 134° read warmer than 135°. It did not. Trust the round numbers — 135° is a designer default for a reason — and spend your real attention on the colors instead.
The midpoint trick: why your gradient goes gray
Here is the problem that makes people give up on gradients: you set a clean blue-to-orange fade, and the middle turns into a dishwater gray-brown. This isn't a bug, and it isn't your monitor. It is how RGB interpolation works.
When the browser blends from blue to orange, it slides each channel — red, green, blue — independently and linearly. Halfway between a saturated blue and a saturated orange, every channel sits near the middle of its range, and an equal mix of all three channels is, by definition, gray. The more opposite your two colors are on the color wheel, the deeper the muddy zone.
There are two fixes. The first is to pick colors closer in hue or lightness — slate-300 to slate-700 bands far less than black to white, because the channels never all crowd into the middle. The second, and the one that saves bold color pairs, is to add a vivid midpoint stop. Drop a third color at 50% that keeps the saturation high — a magenta or a warm pink between your blue and orange — and the gradient routes around the gray pit instead of straight through it. Three well-placed stops kill almost all banding and muddiness at once.
If you grab a hex value mid-blend and it looks gray, run it through the Color Converter to check its actual saturation — a dead giveaway that you need that midpoint stop.
How many stops is too many
More stops is not more beautiful. There's a clear progression.
Two stops is the classic duo-tone — clean, predictable, accessible, and the safest choice for anything behind text. Three to four stops unlocks the "aurora" and "sunset" looks that landing pages love; this is the tasteful sweet spot. Five or more stops starts to read like an oil slick. That can be a deliberate art-direction choice — retro-80s, intentionally chaotic, a hero with no text on it — but it's a disaster behind body copy, where the rapid color shifts wreck readability.
Rule of thumb for text backgrounds: cap it at three stops, and keep adjacent stops within about 30° of hue so the eye reads a smooth wash instead of a busy mess.
Ship it as CSS, not a screenshot
Once your gradient looks right, prefer the raw CSS over an exported image for anything full-bleed. A CSS gradient is resolution-independent — it stays razor-sharp from a 360px phone to a 5K display — and it adds essentially zero bytes to your page. A PNG export earns its keep for static assets: an Open Graph share image, an email header, an app-icon background, or a base you want to dust with film grain in an editor to defeat banding entirely.
Gradients also pair well with their neighbors. Once your hero background is set, a matching box-shadow generator gives your cards depth that sits on the same palette, and a CSS pattern generator can layer subtle texture on top of the fade for a finished, non-generic surface.
Pick a type, place your stops with intent, watch the middle, and stop at three colors when text is involved. That's the whole craft. Everything else is taste — and taste gets faster the more gradients you build.
Made by Toolora · Updated 2026-06-13