DEV Community

Cover image for CSS Gradients in One Screen: linear, radial, conic, and the rules nobody spells out
ToolSura
ToolSura

Posted on • Originally published at toolsura.com

CSS Gradients in One Screen: linear, radial, conic, and the rules nobody spells out

If you've only ever shipped linear-gradient(to right, blue, red), you're using about one-third of what CSS gradients can do. There are only three functions, and the mental model for each is small. Here's the whole thing in one read.

The one fact that makes everything click

A gradient is not an image file. Per MDN, a <gradient> is a special kind of <image> that the browser generates at render time. So it:

  • scales to any size without blurring (it's drawn, not sampled)
  • weighs zero bytes (no file, no HTTP request)
  • edits with one hex value instead of a re-export

That's why gradients exist. Everything below is just how to steer them.

Three functions, three shapes

Function Shape Reach for it when
linear-gradient() straight line along an axis backgrounds, buttons, overlays
radial-gradient() outward from a center point spotlights, glows, vignettes
conic-gradient() rotational sweep around a center pie charts, color wheels, spinners

Linear - the workhorse

background: linear-gradient(to right, #ff7e5f, #feb47b); /* orange→peach */
background: linear-gradient(135deg, #6366f1 0%, #ec4899 100%); /* indigo→pink */
Enter fullscreen mode Exit fullscreen mode

Direction is an angle (45deg) or a keyword (to right, to top right). Stops are a color plus an optional position.

Radial - when the fade should read as light

background: radial-gradient(circle, #fff, #000);
Enter fullscreen mode Exit fullscreen mode

Shape (circle vs ellipse), center position, and sizing keywords (closest-side, farthest-corner) do the work. Because the fade tracks distance from a point, radial reads as depth - perfect for glows, vignettes, and spotlight effects.

Conic - the one most people skip

background: conic-gradient(#f00 0 25%, #0f0 25% 50%, #00f 50% 75%, #ff0 75%);
Enter fullscreen mode Exit fullscreen mode

Conic sweeps by angle, not distance. That single difference makes it the right tool for pie charts and color wheels - effects that were hacky before conic-gradient() shipped.

The rule that surprises everyone

Two color stops at the same position don't fade - they make a hard edge:

background: linear-gradient(to right, #000 50%, #fff 50%);
/* clean half-and-half split, no image file */
Enter fullscreen mode Exit fullscreen mode

That's the entire mechanism behind striped and banded backgrounds. Space the stops and you get stripes; ring them with repeating-radial-gradient() and you get concentric circles.

/* Diagonal stripes, pure CSS */
background: repeating-linear-gradient(45deg, #6366f1 0 20px, #ec4899 20px 40px);
Enter fullscreen mode Exit fullscreen mode

Stacking: the overlay pattern you'll use in every hero

Image properties accept a comma-separated list, and the browser stacks them front to back (first listed on top). Put a transparent dark layer over a colorful base and text on top stays readable:

background:
  linear-gradient(rgba(0, 0, 0, 0.4), transparent),
  /* tint on top */ linear-gradient(to right, #6366f1, #ec4899); /* base gradient */
Enter fullscreen mode Exit fullscreen mode

Reordering the list reorders the stack. This is how mesh backgrounds and texture overlays get built from pure CSS.

Gradients aren't only backgrounds (an <image> goes anywhere)

Because a gradient is an <image>, it works in every property that accepts one:

/* Gradient text */
background: linear-gradient(to right, #6366f1, #ec4899);
-webkit-background-clip: text;
background-clip: text;
color: transparent; /* keep text readable if the gradient fails */

/* Transparent overlay (fade to readable darkness) */
background: linear-gradient(rgba(0, 0, 0, 0.5), transparent);
Enter fullscreen mode Exit fullscreen mode

border-image and mask-image accept gradients too. border-color does not - for gradient borders you use border-image or a wrapper element. (Accessibility note for background-clip: text: the underlay text must remain legible if the degradation path runs; don't let the words disappear.)

Support and paint cost - the two gotchas

  • Support. Linear and radial have been unprefixed in every major browser for 10+ years; caniuse shows near-universal support. Conic arrived later - verify it if you target old browsers. Ignore vendor prefixes unless you need them for legacy.
  • Paint cost. A static gradient paints once and costs nothing measurable. A gradient that animates, covers a huge surface, or stacks many layers can tax the paint step. Rule of thumb: gradients beat background images on load time, and lose to solid colors on paint time. If you animate one, you can't transition gradient values directly between keyframes - interpolate background-position on an oversized gradient instead, or register a @property custom property.

The 5-step recipe

  1. Pick the shape: linear-gradient(), radial-gradient(), or conic-gradient().
  2. Set direction (angle/keyword) or shape+position first.
  3. List two or more color stops - color plus optional position (0%, 20px, 50%).
  4. Assign to background or background-image.
  5. Preview across sizes, nudge stop positions until it lands.

When you want syntax in seconds instead of by hand, a visual CSS gradient generator writes the code for you - pick colors, drag stops, copy.


Three shapes, positioned stops, comma-separated stacks, watch the paint cost when you animate. That's the whole mental model. The spec that nails it all down is CSS Images Module Level 4 if you ever want the precise definition of how interpolation behaves.

Cross-posted from ToolSura.

Top comments (0)