Home / Snippets / Typography /

Gradient text heading

Apply vivid oklch() gradients to heading text using background-clip: text and color: transparent — no images, no SVG.

Design for the web
135deg · purple → blue
Creative direction
90deg · orange → pink
Modern CSS tools
to bottom right · teal → lime
Colour in motion
90deg · four-stop rainbow
Widely Supported
typographycolorno-js

Quick implementation

.gradient-text {
  background-image: linear-gradient(
    135deg,
    oklch(0.72 0.19 265) 0%,
    oklch(0.68 0.22 290) 100%
  );
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;

  /* Fallback for browsers that don't support background-clip: text */
  /* color: oklch(0.72 0.19 265); */
}

Prompt this to your LLM

Includes role, constraints, two framework variants, and edge cases to handle.

You are a senior frontend engineer implementing gradient text headings in CSS.

Goal: Apply a vibrant multi-stop linear gradient to heading text so the
gradient shows through the letterforms — no images, no SVG, no JavaScript.

Technical constraints:
- Use background-image: linear-gradient(...) with oklch() color stops.
  oklch() gives perceptually uniform color transitions between stops.
- Apply both -webkit-background-clip: text and background-clip: text
  (the -webkit- prefix is still required in all major browsers as of 2026).
- Set color: transparent so the element's text color does not paint over
  the gradient background.
- Include a commented-out fallback: color: oklch(...) as the first
  declaration so browsers that ignore background-clip: text still render
  readable text in a solid accent color.
- Use CSS custom properties and oklch() throughout — no hex or rgba values.
- The element must have a defined width or be inline-block / inline-flex;
  a gradient on a block-level element with no explicit width stretches
  across the full container, which may not match the design intent.

Framework variant (pick one):
A) Vanilla CSS utility class .gradient-text plus modifier classes for each
   gradient theme (e.g. .gradient-text--sunset, .gradient-text--ocean).
B) React component — accept a gradient prop (array of oklch stop strings),
   direction prop (e.g. "135deg"), and children; render a <span> with
   inline styles computed from those props.

Edge cases to handle:
- If the element contains inline children (e.g. <em>, <strong>), those
  children inherit color: transparent, making them invisible unless they
  also set an explicit color. Scope the gradient-text styles carefully.
- On Safari, background-clip: text clips to the painted text area, not the
  ink box — descenders and ascenders may be clipped if line-height is tight.
  Add a small padding-bottom (e.g. 0.1em) to prevent clipping.
- Text selection will highlight in the system color, which may contrast
  poorly with transparent text. This is a known limitation; document it.
- Screen readers read the text content normally — color: transparent does
  not affect accessibility. No aria attributes needed.

Return CSS only (or a React component if variant B is chosen).

How background-clip: text works

The background-clip property controls how far a background extends within its element. The text value is the key: instead of filling the element's padding box, the background is clipped to the shape of the rendered text glyphs. Set color: transparent on the same element so the text's own color layer doesn't paint over the background, and the gradient shines through every letterform.

The rendering pipeline is: 1) the browser draws the gradient background behind the element, 2) background-clip: text masks the background to the glyph outlines only, 3) color: transparent ensures the text color layer is invisible, leaving only the clipped gradient visible. The text remains fully in the DOM and read by screen readers — only its visual color is affected.

The -webkit- prefix

-webkit-background-clip: text still needs to be declared alongside the unprefixed property in 2026. Although Chrome, Safari, Edge, and Firefox all support the standard background-clip: text today, the prefixed declaration was the only way to achieve this effect for years, and many browser engines still route through the WebKit implementation. Omitting it risks silent failure on certain WebKit-based environments. Always write both declarations — prefixed first, then standard.

oklch() for gradient stops

The oklch() color space is perceptually uniform: each unit of chroma or lightness change produces a visually equal step regardless of the hue. This matters enormously for gradients. An RGB gradient from blue to yellow passes through a muddy brown midpoint because the two hues are far apart in perceptual space. An oklch gradient between the same endpoints interpolates through perceptually equal steps, staying vivid throughout. Define stops with matching lightness values (e.g. oklch(0.72 0.19 265) and oklch(0.72 0.20 10)) for a gradient that stays bright from edge to edge.

The three axes — lightness (0–1), chroma (0–0.4+), hue (0–360) — map directly onto what designers think about: how light, how saturated, and what colour. Adjusting hue alone while holding lightness and chroma constant produces a rainbow sweep with no brightness variation, which is ideal for multi-stop headings.

Fallback color and progressive enhancement

Opera Mini and a small subset of WebView environments do not support background-clip: text. In those browsers, the gradient background renders behind the text, but the text itself is painted in its declared color. Because the snippet sets color: transparent, unsupported browsers render invisible text — a critical failure.

The fix is a solid fallback: place color: oklch(0.72 0.19 265); as the first declaration. Browsers that support background-clip: text will override it with color: transparent; browsers that don't will keep the solid accent color, rendering legible text. Comment the fallback into the snippet so future editors don't accidentally delete it.

Accessibility

Screen readers read the text content of an element regardless of its CSS. color: transparent is a visual-only instruction — it has no effect on the accessibility tree. Users of assistive technology hear "Design for the web" exactly as they would if the heading were white. No aria-label or visually-hidden text is needed.

Contrast requirements under WCAG 2.1 apply to the full gradient range. Because the gradient transitions through multiple colors, every stop must meet the minimum contrast ratio against the background. Using oklch lightness values above 0.65 on a dark background (--bg: oklch(0.13 0.02 260)) reliably clears the 3:1 threshold for large text (18pt / 14pt bold) required by WCAG AA.