Skip to content
Carl Victor Fontanos
Carl Victor Fontanos

Carl Victor Fontanos

Software Engineer

I build web applications and share what I learn along the way.

© 2026

mask-image: Fade Out Edges Without Baking Gradients into Assets

C
Carlo Fontanos
· 2 min read

You know the "read more" fade - article text dissolving into transparency above the expand button. The common implementation is a white gradient overlay div, which works exactly until dark mode ships and the white smear glows. The correct tool fades the element itself:

.collapsed-article {
    max-height: 220px;
    overflow: hidden;
    mask-image: linear-gradient(to bottom, black 60%, transparent 100%);
}

A mask maps alpha: where the mask is opaque (black), the element shows; where transparent, it vanishes; the gradient between is the fade. Because it's true transparency, any background shows through - dark mode, photos, patterns, no overlay color to maintain. Delete the gradient div.

The scrollable-row hint

Horizontally scrolling tabs and chip rows need to communicate "there's more" - fading the clipped edges does it wordlessly:

.chip-row {
    overflow-x: auto;
    mask-image: linear-gradient(to right,
        transparent, black 24px, black calc(100% - 24px), transparent);
}

Both edges soften; content slides under the fade as you scroll. (The refined version toggles each fade off at the scroll extremes with a few lines of JS - or scroll-driven animations can do it CSS-only in Chromium.) Pairs beautifully with scroll-snap rows.

Icon systems: one SVG, every color

.icon {
    width: 20px; height: 20px;
    background: currentColor;                 /* the color comes from text color */
    mask-image: url(icons/download.svg);
    mask-size: contain;
    mask-repeat: no-repeat;
}

The SVG's shape becomes a stencil over a currentColor block - the icon inherits text color through hovers, themes and states with zero SVG editing, no font-icon hacks, no inline-SVG templating. This is how several design systems ship icons now.

Layering and the fine print

  • Masks stack like backgrounds: comma-separate to combine (fade bottom AND right), with mask-composite controlling how layers combine when you need intersection rather than union.
  • Sizing follows background conventions: mask-size, mask-position, mask-repeat all work as expected.
  • Unprefixed support is universal since late 2023 (Chromium 120); before that Chromium wanted -webkit-mask-*. If your audience skews old-Chrome, ship both spellings - the prefixed ones are harmless duplicates.
  • Distinguish from clip-path: clips are hard-edged geometry, masks are soft alpha. Fades = mask; shapes = clip-path.

Three recipes, one property, and a whole category of overlay-div hacks retired. The fade you add to truncated content today will survive every future theme unchanged - that's the sign you picked the right layer for the effect.

C
Written by Carlo Fontanos

Full-stack web developer sharing practical tutorials and building tools that ship.

Got something on your mind?

My inbox is open - no forms disappearing into the void here.

  • Just say hello Found a tutorial useful? Spotted a mistake? Tell me.
  • Hire me for a project Have something custom in mind? Let's talk scope and timelines.
  • Product support Bought something here? I'll help you get it running.

I usually reply within 1-2 business days.

Message sent!

Your details are only used to reply to you.

Keep reading