Gradients guide

Ink & edges

Gradient Text, Borders & Accents in CSS

On a small area the loudness budget inverts: a headline, a border, or a rule can carry the brand gradient at full strength precisely because it covers so few pixels. These are the accent moves — gradient as ink rather than gradient as light — and each one is a single declaration away from its solid-color version.

Small area, full strength
Accents may use undiluted brand color; the surface behind them may not.
Keep the contrast floor
Every stop in a text gradient must clear contrast on its own — check the palest one.
Plan the fallback
Forced-colors mode strips backgrounds, so clipped text needs a solid color behind it.

Gradient examples

4 effects built from CSS alone

Every swatch below is painted by the declaration beside it — no image files. The stops come from color-mix over your theme tokens, so switch modes and watch each sample follow.

01

Gradient headline

Clip a brand ramp into the display type itself — the one place a gradient may sit directly on words.

Reserve it for display sizes and short lines; at body size the ramp shifts mid-word and reading rhythm pays for it.

.gradient-headline {
  background-image: linear-gradient(90deg,
    var(--primary),
    color-mix(in oklab, var(--primary) 45%, var(--foreground)));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
02

Gradient border

Paint the border with a ramp while the fill stays opaque — two stacked backgrounds clipped to different boxes, no extra element.

The border must be transparent for the trick to show through; a solid border-color on top silently wins and hides the gradient.

.gradient-border {
  border: 1px solid transparent;
  background:
    linear-gradient(var(--card), var(--card)) padding-box,
    linear-gradient(135deg,
      color-mix(in oklab, var(--primary) 60%, transparent),
      color-mix(in oklab, var(--primary) 15%, transparent)) border-box;
}
03

Gradient underline

Run the ramp under a link or heading as a positioned background stripe — an underline that fades out instead of stopping.

This replaces text-decoration, so keep another affordance (color, weight) on links or they stop looking like links mid-fade.

.gradient-underline {
  background-image: linear-gradient(90deg,
    var(--primary),
    color-mix(in oklab, var(--primary) 25%, transparent));
  background-size: 100% 2px;
  background-position: 0 100%;
  background-repeat: no-repeat;
  padding-bottom: 4px;
}
04

Fading divider

Draw a section rule that dissolves at both ends — a hairline gradient that separates without boxing the content in.

Give the fade at least the alpha of a solid border at its center, or the rule disappears entirely on low-contrast panels.

.fading-divider {
  height: 1px;
  background-image: linear-gradient(90deg,
    transparent,
    color-mix(in oklab, var(--foreground) 25%, transparent),
    transparent);
}

Implementation check

Ship the still, solid version everywhere else.

Judge the gradient with real content on top, in both modes, and measure text contrast against the strongest stop it sits on — not the base surface alone. Then park animated surfaces on a still frame for reduced motion, and give clipped text a solid color for forced-color modes.

@media (prefers-reduced-motion: reduce) {
  .animated-gradient { animation: none; }
}

@media (forced-colors: active) {
  .gradient-headline {
    background-image: none;
    color: CanvasText;
  }
}

Carry the light into a complete theme.

Nodlume's theme defines the palette, fonts, shadows, and textures these gradients are mixed from, and generates them into the React project with everything else.

Start planning free

We'd like to use Google cookies to understand how Nodlume is used and to measure our advertising. Nothing loads until you choose, and declining does not affect anything in the app.