Scroll Fade

A CSS utility that fades the edges of any scroll container as you scroll, with no component required.

scroll-fade adds a scroll-aware edge fade to any element that scrolls — a code block, a table wrapper, a third-party list — without wrapping it in a component. It masks the content itself, so the fade dissolves over any background. The effect is driven by CSS scroll-driven animations with no JavaScript, and falls back to a static fade where they aren't supported.

It's the standalone version of the fade built into ScrollArea's nativeScroll mode — same animation, same fallback.

Directly inspired by shadcn's scroll-fade utility, adapted for Cubby UI with a couple of refinements — a fixed-pixel reveal clamped to the scroll range so short scrollers still fully reveal.

The scroll-fade utility works on any scroll container — no component required. Add it to the element that has overflow-y-auto and the edges dissolve as you scroll.

It is driven by CSS scroll-driven animations, so the fade tracks the scroll position with no JavaScript. At the top only the bottom edge fades; mid-scroll both edges soften; at the end the bottom sharpens.

Because it masks the content itself, it adapts to any background without configuration. Use scroll-fade-x for horizontal scrollers and scroll-fade-none to switch it off responsively.

In browsers without scroll-driven animation support, it falls back to a static fade on both edges.

Installation

The utility relies on @property to animate the mask, which can't be injected through the registry's CSS channel — so it ships as a CSS file. Add it, then import it once in your global CSS:

If you already installed the ScrollArea component, this same animation logic is bundled in its scroll-area.css — the utility just exposes it as standalone classes.

Usage

Add scroll-fade to the element that has overflow. It's scroll-aware: at the top only the bottom edge fades; mid-scroll both edges soften; at the end the bottom sharpens.

If the content doesn't overflow, no fade is shown — so you can apply it to any list without checking whether it scrolls.

Classes

ClassEffect
scroll-fade / scroll-fade-yFade top and bottom edges
scroll-fade-xFade left and right edges
scroll-fade-t / -b / -l / -rFade a single edge
scroll-fade-noneDisable — works in any order, e.g. md:scroll-fade-none

Customization

Two CSS variables control the look, the same ones the ScrollArea component uses:

VariableDefaultDescription
--scroll-fade-sizemin(12%, 2.5rem)Fade depth — 12% of the container, capped at 2.5rem.
--scroll-fade-reveal6remScroll distance the fade eases in/out over. Clamped to the scroll range so short scrollers still fully reveal.

Set them per instance with arbitrary properties:

Fallback

The scroll-aware behavior uses CSS scroll-driven animations, with no JavaScript and no scroll listeners. In browsers that don't support them, scroll-fade falls back to a static fade on both edges (and edge utilities to a static fade on the selected edge).

Because the mask is applied to the scroll container itself, a visible scrollbar fades with the content at the edges. Hide it with [scrollbar-width:none] (or your preferred utility) if you want only the content to fade.

Used By

  • ScrollArea — the nativeScroll mode uses this fade internally.