Progressive Blur — .mv-progressive-blur
Pure-CSS progressive edge blur: stacked backdrop-filter layers masked in slices, on any side, with an optional fade to the background color.
| Category | Effects |
|---|---|
| Type | CSS only (.mv-progressive-blur) |
| Status | stable |
| Keywords | blur, progressive-blur, gradual-blur, edge-blur, backdrop-filter, scroll, fade |
When to use
- A scrolling list or feed should soften into its edge instead of being cut off abruptly
- A caption sits at the bottom of an image and the photo should gradually blur beneath it
- A sticky header or bottom bar should blend smoothly into the content scrolling behind it
Avoid when
- A scroll container only needs a thin scrollbar and a simple edge fade → use Scroll Area instead
- Important text or controls would land in the blurriest part of the band
Install
node scripts/add.mjs progressive-blur --out ./src/marvelousAI agent with the Marvelous UI MCP server: install_components({ slugs: ["progressive-blur"], target_dir: "<absolute path>/src/marvelous", framework: "react" }).
Files copied (dependencies included): tokens/tokens.css, core/base.css, components/progressive-blur/progressive-blur.css.
Usage
Canonical markup — start from it and customize with attributes, data-* and CSS variables:
<div style="display:flex;flex-wrap:wrap;gap:1.5rem;justify-content:center;align-items:stretch;width:100%">
<!-- Scrolling list with blurred top and bottom edges -->
<div class="mv-card" style="position:relative;width:min(100%,20rem);height:22rem">
<div style="height:100%;overflow:auto;padding:2.5rem 1.25rem 4rem" tabindex="0" aria-label="Changelog">
<h3 style="margin:0 0 1rem;font-size:var(--mv-text-base)">Changelog</h3>
<ol style="margin:0;padding:0;list-style:none;display:grid;gap:1rem;font-size:var(--mv-text-sm)">
<li><strong>v4.2</strong> — PDF export for dashboards.<br><span style="color:var(--mv-fg-muted)">Sep 18, 2026</span></li>
<li><strong>v4.1</strong> — Offline mode for the mobile app.<br><span style="color:var(--mv-fg-muted)">Sep 2, 2026</span></li>
<li><strong>v4.0</strong> — New real-time collaborative editor.<br><span style="color:var(--mv-fg-muted)">Aug 21, 2026</span></li>
<li><strong>v3.9</strong> — SSO sign-in via SAML and OpenID.<br><span style="color:var(--mv-fg-muted)">Jul 30, 2026</span></li>
<li><strong>v3.8</strong> — 3× faster full-text search.<br><span style="color:var(--mv-fg-muted)">Jul 12, 2026</span></li>
<li><strong>v3.7</strong> — Automatic dark theme.<br><span style="color:var(--mv-fg-muted)">Jun 25, 2026</span></li>
<li><strong>v3.6</strong> — Signed webhooks and audit logs.<br><span style="color:var(--mv-fg-muted)">Jun 3, 2026</span></li>
</ol>
</div>
<div class="mv-progressive-blur" data-side="top" data-fade aria-hidden="true" style="--mv-progressive-blur-size:2.25rem;--mv-progressive-blur-strength:8px"><i></i><i></i><i></i><i></i></div>
<div class="mv-progressive-blur" data-fade aria-hidden="true" style="--mv-progressive-blur-size:6rem"><i></i><i></i><i></i><i></i><i></i><i></i></div>
</div>
<!-- Artwork with a caption over a progressive blur -->
<figure style="position:relative;margin:0;width:min(100%,20rem);height:22rem;border-radius:var(--mv-radius-xl);overflow:hidden;box-shadow:var(--mv-shadow-lg);background:radial-gradient(60% 50% at 30% 30%,oklch(0.85 0.15 85),transparent 70%),radial-gradient(70% 60% at 80% 70%,oklch(0.6 0.22 330),transparent 70%),linear-gradient(160deg,oklch(0.55 0.2 280),oklch(0.35 0.15 250))">
<div aria-hidden="true" style="position:absolute;inset:0;background:repeating-linear-gradient(90deg,oklch(1 0 0 / .18) 0 3px,transparent 3px 22px)"></div>
<div aria-hidden="true" style="position:absolute;left:18%;top:42%;width:8rem;height:8rem;border-radius:50%;background:oklch(0.96 0.03 90)"></div>
<div class="mv-progressive-blur" aria-hidden="true" style="--mv-progressive-blur-size:45%;--mv-progressive-blur-strength:24px"><i></i><i></i><i></i><i></i><i></i><i></i></div>
<figcaption style="position:absolute;inset:auto 0 0 0;z-index:3;padding:1.25rem;color:white;text-shadow:0 1px 10px oklch(0 0 0 / .35)">
<strong style="display:block;font-size:var(--mv-text-lg)">Midnight Sun</strong>
<span style="font-size:var(--mv-text-sm);opacity:.85">“Latitudes” series · limited edition</span>
</figcaption>
</figure>
</div>API
Attributes
| Name | Type | Default | Description |
|---|---|---|---|
data-side | top | bottom | left | right | bottom | Edge toward which the blur increases. |
data-fade | boolean | Adds a gradient to the background color (scrolling lists). |
CSS classes
| Name | Description |
|---|---|
mv-progressive-blur | Absolute layer to place inside a positioned parent (that clips its corners). Holds 1 to 8 empty children (<i>): one blur layer each; 6 gives a very smooth gradient. With no children, 2 layers via pseudo-elements. |
CSS variables
| Name | Default | Description |
|---|---|---|
--mv-progressive-blur-size | 35% | Height (or width) of the band. |
--mv-progressive-blur-strength | 16px | Maximum blur, at the edge. |
--mv-progressive-blur-fade | var(--mv-bg) | Fade color (data-fade). |
--mv-progressive-blur-z | 2 | Layer z-index. |
Accessibility
Decorative: aria-hidden and pointer-events: none, so the content underneath stays clickable and scrollable. No animation. Keep important text out of the blurriest area (or place the caption above it, as in the demo).