ToolZen ToolZen
Graphics generator client

Gradient Generator

Create custom linear and radial CSS gradients with a live preview. Adjust colors and angle, then copy the CSS property.

Advertisement (Top Banner)
Color 1
Color 2
135°
Advertisement (Bottom)

A CSS gradient is two or more colours and a direction, and the browser fills in everything between. The filling-in is where it gets interesting, because the default way browsers interpolate colour is the reason so many gradients look muddier than the colours that went into them.

CSS angles are not maths angles

This trips up anyone who has done any trigonometry. In maths, 0 degrees points right and angles increase anticlockwise. In CSS gradients, 0deg points up and angles increase clockwise. The two conventions are rotated 90 degrees apart and spin in opposite directions.

So 90deg is to the right, 180deg is downwards, 270deg is to the left. If a gradient is coming out rotated from what you expected, this is almost always why — and the fix is not to fiddle with the number until it looks right, it is to know that CSS starts at the top and turns the way a clock does.

The keyword syntax exists to sidestep the whole thing: to right, to bottom left. It reads better than a number and cannot be confused with anything, which makes it the better choice whenever the direction is one of the eight obvious ones.

The muddy middle, and where it comes from

Put a saturated blue and a saturated yellow in a gradient and watch what happens in the middle: it goes grey. Not a pleasant transitional colour — a dead, washed-out band that neither colour would have predicted.

The cause is the same one that makes #808080 not half as bright as white. By default browsers interpolate gradients in sRGB, and sRGB numbers are not quantities of light — they are perceptually encoded. Averaging them is arithmetic on the wrong scale, and it lands somewhere darker and less saturated than the eye expects. The midpoint of two vivid colours comes out drained.

CSS now lets you say where to interpolate. Writing linear-gradient(in oklch, blue, yellow) tells the browser to blend in a perceptual space, and the muddy band simply does not appear — the transition stays vivid the whole way across. It is supported in every current browser and it is the single change that most improves a gradient built from saturated colours. This tool generates the standard syntax; adding "in oklch" after the angle is a manual edit worth making.

Banding is arithmetic, not a rendering bug

Subtle gradients band. A gentle wash across a hero section shows visible stripes, and no amount of adjusting the colours fixes it. The reason is that eight bits per channel gives you 256 values, and a gradient can only use the values that exist between its endpoints.

Measure it and it is stark. A gradient from #404040 to #484848 has eight levels of difference to work with, and stretching it across a thousand pixels produces nine distinct shades — nine steps, each over a hundred pixels wide. Those are the bands. There is no missing precision to recover; the colours are simply that close together.

The fixes are all workarounds. Overlay a faint noise texture, which breaks the flat regions into dither and hides the boundary. Use a wider colour difference across the same distance. Or accept it, since banding is far less visible on a busy page than on a blank one. What does not work is asking the browser to try harder, because it is already at the limit of what the format can express.

The transparency trap

Fading a colour to nothing is written as a gradient from that colour to transparent, and in Safari it used to go grey in the middle — because transparent was interpreted as rgba(0,0,0,0), a fully transparent black, and blending toward it dragged everything through invisible black on the way.

Modern browsers interpolate in premultiplied alpha, which fixes it. But the habit worth keeping is to spell out the endpoint explicitly: rgba(255,0,0,1) to rgba(255,0,0,0) says what you mean, cannot be misread by anything, and does not rely on the browser doing the right thing with a keyword.

Common questions

Is anything sent to a server?

No. This tool is marked "client": the preview is your own browser rendering the CSS, and the rule is assembled from your inputs in the page. Nothing is transmitted.

Why does the middle of my gradient look grey?

sRGB interpolation, described above. The two colours are being averaged on a scale that is perceptually encoded rather than linear, which lands the midpoint darker and flatter than expected. Add "in oklch" after the angle and it goes away — the browser then blends in a space designed for exactly this.

How do I get rid of the stripes in a subtle gradient?

You cannot, not directly — they come from having only 256 levels per channel, and a subtle gradient uses very few of them. The practical answer is a faint noise overlay, which dithers the boundaries into invisibility. It is the same trick print has used for a century, and it is why so many "smooth" gradients on well-made sites have a barely perceptible grain over them.

Linear or radial?

Linear for anything that reads as a surface — a background, a button, a section. Radial for anything that reads as a light source or a focal point, because that is what a radial gradient physically looks like. If you find yourself unsure, it is linear: radial gradients draw attention to their centre, and if there is nothing at the centre worth attending to, the gradient is asking a question the design does not answer.

Do gradients hurt performance?

Not meaningfully. A CSS gradient is painted once and costs less than the image you would otherwise have loaded — it is bytes you did not download. Where it does cost is animation: animating gradient stops forces a repaint every frame, which is expensive. If you need a moving gradient, animate the transform of an oversized gradient element instead, and let the compositor do the work.