# Transparent gradients in CSS: fades, overlays and scrims

[Canonical HTML page](https://gradiently.design/guide/css-gradient-transparent)

A gradient that fades to nothing is one of the most useful tools in CSS. It also used to leave a grey smudge in the middle. Here is how transparency in gradients works now, and the patterns worth keeping.

## The short version

- To make a CSS gradient transparent, use a colour with zero alpha as one of the stops, such as transparent or rgb(124 58 237 / 0).
- Modern browsers interpolate gradient colours with premultiplied alpha, so fading a colour to the transparent keyword no longer produces a grey band.
- A background gradient can only fade the background; to fade an element's actual content, use mask-image with a gradient.
- A scrim with several eased stops looks smoother than a two stop fade, which shows a visible edge where the darkening stops.
- A radial gradient that is transparent in the centre and dark outside makes a spotlight that draws attention to one area.

To make a **CSS gradient transparent**, give one of its stops a colour with zero alpha: `linear-gradient(to bottom, #7c3aed, transparent)` fades violet to nothing, letting whatever sits underneath show through. Use the same idea for fades at the end of text, dark scrims behind captions and coloured overlays on photos. For fading an element's content rather than its background, use `mask-image` with a gradient instead.

## Ways to write a transparent colour

| You write | Means | Use it when |
| --- | --- | --- |
| `transparent` | Black at zero alpha | Fading any colour out, in modern browsers |
| `rgb(124 58 237 / 0)` | This violet at zero alpha | Being explicit, or supporting very old browsers |
| `rgb(124 58 237 / 0.4)` | This violet at 40 percent | A tint that never fully disappears |
| `#7c3aed66` | Eight digit hex, about 40 percent | Design tools that export hex with alpha |
| `color-mix(in srgb, var(--brand) 40%, transparent)` | A variable's colour at 40 percent | Colours stored in custom properties |

Five ways to say the same kind of thing. The `color-mix()` form is the only one that works on a colour you only know as a variable; see [color-mix() in CSS](https://gradiently.design/guide/css-color-mix).

## Why fades used to turn grey

The keyword `transparent` is black with zero alpha. Early browsers blended the red, green and blue channels and the alpha channel separately, so a fade from white to `transparent` passed through half transparent grey on the way. That is why older tutorials insist on `rgba(255, 255, 255, 0)` instead.

The specification now requires premultiplied alpha: each colour is weighted by its opacity before blending, so a fully transparent stop contributes no colour at all. Every current browser does this. Writing the matching colour at zero alpha is still a harmless habit, and it keeps you safe in email clients and old WebViews.

### Old behaviour

- White to `transparent` dips through grey
- Colour channels blended without regard to opacity
- Workaround: repeat the colour at zero alpha

### Current browsers

- White to `transparent` stays white as it fades
- Premultiplied alpha, as the specification requires
- Either form works; the explicit one is more portable

- Violet fading out: `linear-gradient(to bottom, #7c3aed 0%, rgb(124 58 237 / 0) 100%)`
- Teal fading by 70 percent: `linear-gradient(to right, #0f766e 0%, rgb(15 118 110 / 0) 70%)`
- Orange glow on nothing: `radial-gradient(circle at 30% 30%, #f97316 0%, rgb(249 115 22 / 0) 60%)`

Three fades shown over this page's own background, which is exactly what they do in your layout. Stack fades like these over a base colour to build soft, layered backgrounds.

Where the fade ends matters as much as its colours. A stop at 70 percent finishes the fade early and leaves the rest of the box fully clear, which is ideal for a tint that should only touch one edge. Two stops at the same position make a hard cut from colour to nothing, useful for half filled bars and split backgrounds. Stop positions are explained in [CSS linear gradients](https://gradiently.design/guide/css-linear-gradient).

## Fading content with mask-image

A background gradient sits behind the content, so it cannot fade text, images or a scrolling list. A mask can. With `mask-image`, opaque parts of the gradient keep the element visible and transparent parts hide it. The colour of the mask doesn't matter, only its alpha.

```css
/* Fade the last lines of a teaser paragraph */
.teaser {
  max-height: 9rem;
  overflow: hidden;
  mask-image: linear-gradient(to bottom, #000 60%, transparent);
}

/* Soft edges on a horizontally scrolling row */
.carousel {
  overflow-x: auto;
  mask-image: linear-gradient(to right, transparent, #000 48px, #000 calc(100% - 48px), transparent);
}

/* Fade a photo into the page on any background colour */
.hero-photo {
  mask-image: linear-gradient(to bottom, #000 50%, transparent 95%);
}
```

Masks fade whatever is there, on any page colour, light or dark. Unprefixed `mask-image` works in current browsers; add `-webkit-mask-image` for older Safari.

The old alternative was a white gradient laid over the content. It breaks the moment the page is not white, in [dark mode](https://gradiently.design/guide/dark-mode-design) for instance, and it blocks clicks unless you remember `pointer-events: none`. A mask has neither problem.

## Scrims: transparent gradients for text

A scrim darkens part of an image so text on it reads, fading to fully transparent so the rest of the photo stays bright. A two stop fade works, but its straight ramp leaves a visible line where the darkening ends. More stops, spaced to ease out, hide that edge.

Eased scrim, seven stops: `linear-gradient(to top, rgb(2 6 23 / 0.8) 0%, rgb(2 6 23 / 0.62) 15%, rgb(2 6 23 / 0.42) 30%, rgb(2 6 23 / 0.24) 48%, rgb(2 6 23 / 0.1) 66%, rgb(2 6 23 / 0.03) 82%, rgb(2 6 23 / 0) 100%)`

Opacity falls quickly near the text and slowly near the top, which reads as natural shade instead of a band.

```css
.card {
  background-image:
    linear-gradient(to top,
      rgb(2 6 23 / 0.8) 0%, rgb(2 6 23 / 0.62) 15%, rgb(2 6 23 / 0.42) 30%,
      rgb(2 6 23 / 0.24) 48%, rgb(2 6 23 / 0.1) 66%, rgb(2 6 23 / 0.03) 82%,
      rgb(2 6 23 / 0) 100%),
    url("/images/coast.jpg");
  background-size: cover;
  color: #f8fafc;
}
```

The scrim is the first background layer, so it sits on top of the photo.

Tint the scrim with a deep version of the photo's colour rather than pure black and it will feel part of the picture. On a warm sunset photo, a deep brown such as `rgb(41 20 8 / 0.75)` sinks into the image, where black would look like a filter laid on top. [Gradient overlays in CSS](https://gradiently.design/guide/css-gradient-overlay) covers colour washes and blend modes, and [text over images](https://gradiently.design/guide/text-over-image) covers placement.

## Transparent holes and spotlights

Flip the idea: transparent in the middle, dark outside. A [radial gradient](https://gradiently.design/guide/css-radial-gradient) laid over a page or image leaves one area lit and quietly dims everything else, which suits onboarding tips, product close ups and slides.

```css
.spotlight::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(
    circle at var(--x, 50%) var(--y, 40%),
    transparent 0 140px,
    rgb(2 6 23 / 0.72) 220px
  );
}
```

Set `--x` and `--y` from JavaScript to move the spotlight. The 80 pixel blend between the stops keeps the edge soft.

A portrait product post where the headline sits over a bright area of the gradient

Without any shaping, words compete with the brightest part of the background.

The same product post with a calmer, deeper area of the gradient behind the headline

The background quiets itself behind the words, the job a scrim does on a website.

For social posts and print, you rarely need to hand build scrims. In Gradiently the Mark itself makes room for your words, deepening or lifting the colours near the letters, with no overlay layer to tune for each size.

## FAQ

### How do I make a CSS gradient fade to transparent?

Use a zero alpha colour as the last stop: `linear-gradient(#7c3aed, transparent)` or, to be explicit, `linear-gradient(#7c3aed, rgb(124 58 237 / 0))`.

### Why does my gradient to transparent look grey?

Older browsers blend without premultiplied alpha, so `transparent` (transparent black) greys the middle. Fade to your colour at zero alpha instead.

### How do I fade out text or an image with CSS?

Use `mask-image` with a gradient, such as `mask-image: linear-gradient(#000 60%, transparent)`. The element fades on any background colour.

### What is a scrim in CSS?

A gradient that darkens part of an image behind text and fades to transparent elsewhere, so the text reads and the image stays bright.

### Can a CSS gradient have a transparent hole?

Yes. A radial gradient that is transparent at the centre and dark further out leaves a clear spotlight over whatever sits beneath.
