Skip to content
PaletteViva
Appearance

Gradient generator

Set two to eight colour stops and an angle, and copy CSS you can paste straight into a stylesheet. The preview is painted with the same value the copy button gives you, so what you see is what you get rather than what you hope matches.

Preview

Angle 135°

background: linear-gradient(135deg, #3e7a66 0%, #ffffff 100%);

2 stops, in order. The gradient is not saved — its colours are.

Gradient controls

Any angle works: -90 becomes 270, and 450 becomes 90.

Colour stops (2 of 8)

Listed in the order they run across the gradient, because that is the order CSS paints them in. The arrows move a stop past its neighbour; a colour at the very start or end has nothing to move past, so its arrow is off.

Every colour field accepts hex, rgb(), hsl() or oklch(). Alpha is not supported; this tool is opaque-only.

A new stop is added in the widest gap, at the colour the gradient already paints there, so adding one changes nothing until you move or recolour it. Remove is disabled at 2 stops, the fewest a gradient can have.

The value you copy is the value you see

The preview above is not a picture of a gradient; it is an element whose background-image is the gradient value, and the code block under it prints that same string with background: in front and a semicolon behind. Copy either button and you get the text that is on screen, character for character — not a second rendering of the same settings, which is where a tool and its output normally start to disagree.

That is a checkable claim rather than a slogan, so the test suite checks it as one: it clicks the copy button, reads the clipboard back, and compares it to the code block, and it separately reads the browser's own painted pixels for the preview and compares them against a gradient built from the text in that block. Three descriptions of one gradient, held against each other.

Why this tool keeps the stops in order

CSS does not reject a stop that sits before the one above it — it quietly moves it. Painted and measured in the browser, linear-gradient(90deg, #ff0000 80%, #0000ff 20%) is red across the first 80% and blue for the rest: the second stop's 20% is not honoured at 20%, it is clamped up to 80%. The declaration is valid, it renders, and it does not mean what it says.

So this editor holds its stops in ascending order and writes them that way, which is why dragging a stop past a neighbour moves its row in the list. The alternative — keeping whatever order you typed and letting the browser reinterpret it — would mean shipping a code block that describes a gradient other than the one you are looking at. Reordering a list is a smaller surprise than that.

Two stops may share a position, which is how you make a hard edge rather than a blend, and is deliberate rather than an invalid state. At exactly that position the later stop is the one that paints, which was measured the same way. The list shows them in that order for that reason.

Adding a stop without changing the gradient

Add stop does not append to the end or drop a handle at 50%. It inserts a stop in the widest gap, coloured with whatever the gradient already paints at that point, so the picture does not move until you tell it to. A click that was meant to make something editable should not repaint the thing you were looking at, and there is no undo to walk that back.

That works because of how the browser interpolates by default. With no interpolation hint, a gradient blends in gamma-encoded sRGB, straight across each stop's 8-bit channels. Measured from a painted element, black to white reads #818181 at the midpoint — where linear-light interpolation would read about #bcbcbc and OKLab about #777777. Because each segment is straight, a stop placed on a segment with the colour that is already there does not bend it. This tool does the same arithmetic, which is what makes the insert invisible rather than nearly invisible.

Angles, and what they mean

The angle is the direction the gradient runs, measured clockwise from the top: 0deg runs top to bottom, 90deg left to right, and 180deg bottom to top. 135deg runs from the top-left corner to the bottom-right one — measured, not assumed, and the direction most "diagonal" gradients people reach for actually want.

Angles are normalised into a single turn, so one direction has one spelling: -90 becomes 270 and 450 becomes 90. Type any integer into the degrees field and the code block will show you the normalised value it used, which keeps the number on screen and the number in the CSS from being two different things.

What this tool does not do

  • Linear gradients only. Radial and conic gradients are different tools, not extra options on this one, and neither is half-built here.
  • No transparency. Every stop is opaque, as everywhere else on this site. Alpha is not silently dropped from a value you typed; it is refused.
  • No interpolation-space switch. The emitted value uses the default sRGB blend, which is the form every browser renders identically. Interpolation spaces are a CSS feature this tool deliberately does not emit.
  • Eight stops. A gradient needing more is usually a background layer or an image rather than a longer list of handles.
  • Stop colours are 8-bit, and the screen is too. The browser blends between stops at higher precision, but what reaches the display is 8 bits per channel, so a long and very subtle ramp can band. That is a property of the display, not of the CSS — and on a wide-gamut screen the same values can read differently again, which has its own explanation .

Where to go next

This page builds the gradient itself — the CSS background gradient you would put behind a card, a hero, a button, or a section. If you want that same kind of gradient running through the letters instead, the gradient text generator uses it as the fill behind text, so the gradient and the words stay separate concerns: one makes the ramp, the other decides where to show it.

Gradient colours usually come from somewhere. The image color picker reads an exact pixel out of a photograph, and palette from image gives you a whole set worth building a gradient from.

Once you have the two colours, the contrast checker says whether text set in one clears WCAG AA against the other — worth doing before the gradient goes behind a heading. And the color converter translates either colour into HEX, RGB, HSL, HSV, OKLCH and CMYK if you need it in another form.

If you only have the first colour, the harmony generator computes the second — a complement or a triadic partner rather than a guess.