Scroll Mask

Fades the scrollable edges of any container with a CSS mask, hinting at hidden content above, below, or beside the viewport.

Tags

v1.2.0-beta.50
v1.2.0-beta.49
v1.2.0-beta.48
v1.2.0-beta.47
v1.2.0-beta.46
v1.2.0-beta.45
v1.2.0-beta.44
v1.2.0-beta.43
v1.2.0-beta.42
v1.2.0-beta.41
v1.2.0-beta.40
v1.2.0-beta.39
v1.2.0-beta.38
v1.2.0-beta.37
v1.2.0-beta.36
v1.2.0-beta.35
v1.2.0-beta.34
v1.2.0-beta.33
v1.2.0-beta.32
v1.2.0-beta.31
v1.2.0-beta.30
v1.2.0-beta.29
v1.2.0-beta.28
v1.2.0-beta.27
v1.2.0-beta.26
v1.2.0-beta.25
v1.2.0-beta.24
v1.2.0-beta.23
v1.2.0-beta.22
v1.2.0-beta.21
v1.2.0-beta.20
v1.2.0-beta.19
v1.2.0-beta.18
v1.2.0-beta.17
v1.2.0-beta.16
v1.2.0-beta.15
v1.2.0-beta.14
v1.2.0-beta.13
v1.2.0-beta.12
v1.2.0-beta.11
v1.2.0-beta.10
v1.2.0-beta.9
v1.2.0-beta.8
v1.2.0-beta.7
v1.2.0-beta.6
v1.2.0-beta.5
v1.2.0-beta.4
v1.2.0-beta.3
v1.2.0-beta.2
v1.2.0-beta.1
import * as React from "react"

import { ScrollMask } from "@/components/ui/scroll-mask"

Scroll Mask wraps scrollable content and applies a mask-image gradient to its edges, so content literally fades to transparent as it leaves the viewport — the same affordance used by the fumadocs sidebar. Because it uses a mask rather than a colored overlay, it works on any background. Each edge only fades once there is content scrolled past it.

Installation

pnpm dlx shadcn@latest add https://ui.tyap.me/r/styles/base/scroll-mask.json

Usage

import { ScrollMask } from "@/components/ui/scroll-mask"
<ScrollMask className="h-72 w-48 rounded-md border">
  Your scrollable content here.
</ScrollMask>

ScrollMask is the scroll container itself, so drop any tall or wide content inside it. It is built to be embedded inside other components — sidebars, command lists, pickers — wherever a scroll region needs softened edges.

Examples

Horizontal

Set orientation="horizontal" to fade the left and right edges of a horizontally scrolling row.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import * as React from "react"

import { ScrollMask } from "@/components/ui/scroll-mask"

Both axes

Use orientation="both" to mask all four edges. The vertical and horizontal masks are composited together so corners stay correct.

0-0
0-1
0-2
0-3
0-4
0-5
0-6
0-7
0-8
0-9
0-10
0-11
1-0
1-1
1-2
1-3
1-4
1-5
1-6
1-7
1-8
1-9
1-10
1-11
2-0
2-1
2-2
2-3
2-4
2-5
2-6
2-7
2-8
2-9
2-10
2-11
3-0
3-1
3-2
3-3
3-4
3-5
3-6
3-7
3-8
3-9
3-10
3-11
4-0
4-1
4-2
4-3
4-4
4-5
4-6
4-7
4-8
4-9
4-10
4-11
5-0
5-1
5-2
5-3
5-4
5-5
5-6
5-7
5-8
5-9
5-10
5-11
6-0
6-1
6-2
6-3
6-4
6-5
6-6
6-7
6-8
6-9
6-10
6-11
7-0
7-1
7-2
7-3
7-4
7-5
7-6
7-7
7-8
7-9
7-10
7-11
8-0
8-1
8-2
8-3
8-4
8-5
8-6
8-7
8-8
8-9
8-10
8-11
9-0
9-1
9-2
9-3
9-4
9-5
9-6
9-7
9-8
9-9
9-10
9-11
10-0
10-1
10-2
10-3
10-4
10-5
10-6
10-7
10-8
10-9
10-10
10-11
11-0
11-1
11-2
11-3
11-4
11-5
11-6
11-7
11-8
11-9
11-10
11-11
12-0
12-1
12-2
12-3
12-4
12-5
12-6
12-7
12-8
12-9
12-10
12-11
13-0
13-1
13-2
13-3
13-4
13-5
13-6
13-7
13-8
13-9
13-10
13-11
14-0
14-1
14-2
14-3
14-4
14-5
14-6
14-7
14-8
14-9
14-10
14-11
15-0
15-1
15-2
15-3
15-4
15-5
15-6
15-7
15-8
15-9
15-10
15-11
16-0
16-1
16-2
16-3
16-4
16-5
16-6
16-7
16-8
16-9
16-10
16-11
17-0
17-1
17-2
17-3
17-4
17-5
17-6
17-7
17-8
17-9
17-10
17-11
18-0
18-1
18-2
18-3
18-4
18-5
18-6
18-7
18-8
18-9
18-10
18-11
19-0
19-1
19-2
19-3
19-4
19-5
19-6
19-7
19-8
19-9
19-10
19-11
20-0
20-1
20-2
20-3
20-4
20-5
20-6
20-7
20-8
20-9
20-10
20-11
21-0
21-1
21-2
21-3
21-4
21-5
21-6
21-7
21-8
21-9
21-10
21-11
22-0
22-1
22-2
22-3
22-4
22-5
22-6
22-7
22-8
22-9
22-10
22-11
23-0
23-1
23-2
23-3
23-4
23-5
23-6
23-7
23-8
23-9
23-10
23-11
import * as React from "react"

import { ScrollMask } from "@/components/ui/scroll-mask"

API Reference

The component renders a div and forwards every native div prop. The following props control the mask.

PropTypeDefaultDescription
orientation"vertical" | "horizontal" | "both""vertical"Which axis gets a fade at its scrollable edges.
sizenumber | string"2rem"Length of the fade. A number is treated as pixels; any CSS length is passed through.
alwaysbooleanfalseKeep the fade visible even when an edge is not scrollable, instead of revealing it only on overflow.
disabledbooleanfalseRemove the mask while keeping the scroll container, for toggling the effect without unmounting children.