Gradient Generator

Write a linear, radial or conic CSS gradient from your own colour stops, and copy the declaration.

Runs on your deviceDesign & ColorWorkingNo account needed

What this tool does

Gradient Generator turns a set of colour stops into a CSS declaration, and shows the result three ways at once: a 180-pixel preview band painted with the gradient, the code itself, and a table listing every stop with its colour and position. It runs from its settings alone — leave the input box empty and the Start colour and End colour pickers become a two-stop gradient at 0% and 100%. Type stops into the box and they replace the pickers entirely.

Stops are written one per line, as a colour followed by an optional position. The colour can be hex in 3, 4, 6 or 8 digits, a CSS colour name, transparent, or a functional value: rgb(), hsl(), hwb(), lab(), lch(), oklab(), oklch() and color() in the srgb and srgb-linear spaces. A value that cannot be read stops the run with the line number attached, rather than being dropped without a word. A stop may carry two positions, which is the double-position syntax that produces a hard edge instead of a blend.

Even spacing is applied only when no stop carries a position at all: two bare colours become 0% and 100%, three become 0%, 50% and 100%. As soon as one position is written, the others are left empty for the browser to interpolate, and the table marks them as browser default. That is deliberate rather than lazy — inventing a middle position for a list that runs 10%, then nothing, then 20% would place a stop after the one that follows it, and browsers silently clamp that back. Unless the property is mask-image, the output also carries a background-color line set to the first stop, so anything that cannot parse the gradient still paints a flat colour.

The limits are in the syntax it will not write. Direction is always an angle, so there is no keyword form such as to right; a radial gradient takes one of nine centre keywords and no size keyword like farthest-corner; there are no interpolation hints such as in oklch; and one run produces one gradient function, so layered backgrounds are assembled by hand. Every stop is normalised to sRGB hex on the way out, which means an oklch() colour comes back as the nearest hex and the gradient interpolates in sRGB. It is a generator, not a parser: an existing gradient declaration cannot be pasted in to be edited. None of it needs a server. The stops are parsed and the declaration assembled by this page, so the generator still works with the connection cut.

How to use it

  1. Choose the gradient type. Linear, radial or conic. The angle slider appears for linear and conic, the circle or ellipse shape only for radial, and the centre keyword for radial and conic.
  2. Set the colours. Leave the input box empty to use the two colour pickers. For more than two stops, type one per line as a colour and an optional position, such as #3B82F6 0%. Blank lines are skipped, and a line beginning with a double slash, or a hash followed by a space, is treated as a comment — a hex value is not.
  3. Aim it. For a linear gradient the angle is the direction it travels: 0deg points to the top and the angle increases clockwise, so 135deg runs from the top-left corner towards the bottom-right. For conic it is the angle the sweep starts from, pivoting on the centre you chose.
  4. Pick the property, and repeating if you want it. background-image, the background shorthand, or mask-image. Ticking Repeating gradient switches the function to its repeating- form, which tiles the stop list beyond the last position instead of holding that colour flat.
  5. Copy the declaration. Copy output places the CSS on the clipboard — the gradient line, plus the background-color fallback where one applies. Nothing is downloaded; the text is the whole deliverable.

Processing & privacy

Runs on your device. Your file is processed directly in this browser.

Common use cases

Giving a hero section a background

Two brand colours on a diagonal is the usual answer, and the preview band shows whether the midpoint turns muddy before the declaration reaches a stylesheet.

Drawing a progress ring or a pie

A conic gradient with double-position stops paints hard segments without an SVG, and the centre keyword decides where the sweep pivots.

Making stripes

Repeating with a short final position tiles the stops across the whole box, which is how a striped or barber-pole background comes from a single declaration.

Fading an element out at one edge

Set the property to mask-image and end the stop list on transparent, so the element itself fades instead of sitting under a matching coloured overlay.

Tidying stop colours before they become tokens

The table lists every stop in order as an uppercase hex value, which is a quick way to get consistent values out of a list that mixes names, rgb() and oklch().

Questions

Does my stop list get uploaded?
No. Parsing the colours, writing the CSS and drawing the preview all happen in this browser tab, so no colour or stop list is transmitted or stored, and the tool still works with the connection dropped.
Can I paste in a gradient I already have?
No. The input box reads colour stops, not CSS, so a pasted linear-gradient declaration is rejected with an error naming line 1. Retype the stops one per line, or rebuild the gradient from the settings.
My stops are in oklch — why is the output hex?
Every stop is converted to sRGB and written as a hex value, with an eight-digit hex when it carries alpha. The gradient therefore interpolates in sRGB, and a wide-gamut colour is reduced to its nearest sRGB equivalent.
Why do some of my stops have no position?
Positions are spread evenly only when not one stop has been given a position. Write a position on any stop and the remaining ones are left for the browser to space, which the table reports as browser default. It avoids emitting a position that would sit out of order and be clamped.
Can I use to right instead of an angle?
No, the direction is always written in degrees. In CSS 0deg points to the top and the angle turns clockwise, so to right is 90deg, to bottom is 180deg, and the slider covers the full 360.
Why does the preview look the same when I choose mask-image?
The preview band always paints the value as a background-image, whichever property you selected. With mask-image you are looking at the alpha ramp rendered as colour rather than the mask applied to an element — the code is right, the preview simply is not a mask.
Can it write two gradients on one property, or an interpolation hint?
No. One run produces one gradient function, and modern extras such as in oklch or longer hue are not emitted. Layering and interpolation have to be added to the declaration yourself.
What is the background-color line for?
It repeats the first stop as a flat colour, so a browser that cannot parse the gradient still shows something sensible underneath. It is omitted for mask-image, where a background colour would be the wrong thing to emit.
What is the smallest gradient it will make?
Two stops. A single line is refused with a message saying a gradient needs at least two colour stops, because one colour is a flat background rather than a gradient.

Related tools