MD3
Expressive
MATERIAL DESIGN 3 EXPRESSIVE

Fading Blur Mask

Hardware-accelerated linear gradient backdrop blur and surface tint overlay for seamless scrolling containers.

The Fading Blur Mask is a high-performance visual overlay primitive designed to eliminate harsh clipping boundaries in scrollable interfaces. It separates directional backdrop blur and Material Design 3 surface tint into two independent gradients, so blur and color recede together without visible banding or a cutoff.

Loading demo...

Introduction

In modern expressive interfaces, content often scrolls continuously behind floating or pinned navigation elements. Standard translucent surfaces or abrupt solid borders can create sharp visual cuts that break immersion.

The MD3 Expressive Fading Blur Mask solves this by generating a continuous gradient falloff:

  • At the outer boundary (e.g., top of the screen), the mask is opaque with full surface tinting and maximum backdrop blur.
  • Toward the viewport center, both the backdrop blur and surface color smoothly attenuate to zero opacity, allowing underlying content to show cleanly.

It is built as both an independent primitive (<FadingBlurMask>) and as a built-in mixin (enableFadingBlur) for MD3 Expressive App Bars.

Anatomy

  • Container Layer: Positioned absolutely (absolute inset-0 z-0) with pointer-events: none and aria-hidden="true" so it never intercepts user touch/clicks or pollutes screen reader trees.
  • Backdrop Blur Layer: One backdrop-filter overlay uses -webkit-mask-image / mask-image to fade the requested blurIntensity continuously. Blur automatically disables when reduced motion is preferred.
  • Tint Layer: A sibling overlay applies the color with the identical directional mask, avoiding the compositing artifacts caused by tinting the blur layer itself.
  • Surface Color Tint: The tint follows the same fade as blur, so any MD3 token, CSS variable, or CSS color blends without a hard cutoff.
  • Content Slot: Supports optional child elements rendered within the mask coordinate system.

Variants

Directional Presets

The mask supports three directional modes depending on where content enters or exits the scroll viewport:

  • Top (direction="top"): Opaque at the top, fading to transparent downward. Ideal for Top App Bars, collapsible headers, and search bars.
  • Bottom (direction="bottom"): Opaque at the bottom, fading to transparent upward. Designed for Bottom App Bars, docked toolbars, and sticky footers.
  • Both (direction="both"): Fades simultaneously at both top and bottom edges. Suitable for modal dialog viewports, inline carousels, or centered scroll areas.
Loading demo...

App Bar Integration

The fading blur effect is built directly into all MD3 Expressive App Bar components via the enableFadingBlur mixin prop.

Loading demo...

Features

Hardware Acceleration & Mask Gradients

Two lightweight, non-interactive sibling layers share one directional gradient:

  • Top: Maximum blur and tint at the top edge, then a continuous fade toward the content.
  • Bottom: The equivalent transition from the bottom edge upward.
  • Both: Independent mirrored transitions at both edges, with a clear center.

Accessibility & Reduced Motion

The component integrates with useReducedMotion() from motion/react. When a user enables system-level prefers-reduced-motion, the backdrop blur intensity automatically drops to 0px to conserve GPU resources and reduce visual vestibulary strain.

Flexible Dimensions & Colors

You can customize:

  • blurIntensity: Default 12px, customizable up to 32px or higher.
  • blurHeight: Supports CSS strings (e.g. "64px", "100%") or numeric pixel values.
  • color: Defaults to var(--md-sys-color-surface), but accepts any color string (e.g. surface containers or translucent tinted alphas).

Usage

Standalone Usage

import { FadingBlurMask } from "@bug-on/m3-expressive/layout";
// Alternatively import from subpaths:
// import { FadingBlurMask } from "@bug-on/m3-expressive/layout";
// import { FadingBlurMask } from "@bug-on/m3-expressive/navigation";

export function ScrollContainerWithMask() {
  return (
    <div className="relative h-96 w-full overflow-hidden rounded-2xl border">
      {/* Positioned inside a relative container */}
      <FadingBlurMask
        direction="top"
		blurIntensity={16}
		blurHeight={72}
		color="var(--md-sys-color-surface-container)"
      />

      {/* Scrollable content */}
      <div className="h-full overflow-y-auto p-4 space-y-3">
        {/* items */}
      </div>
    </div>
  );
}

With App Bars

import { SmallAppBar } from "@bug-on/m3-expressive/navigation";

<SmallAppBar
  title="Collapsible Header"
  enableFadingBlur
  blurIntensity={16}
	blurHeight={64}
	fadingBlurColor="var(--md-sys-color-surface-container)"
/>

Best Practices

Do

  • Use direction="top" for pinned top navigation and direction="bottom" for docked bottom toolbars.
  • Keep pointerEvents: none active so underlying interactive elements remain clickable.
  • Maintain contrast with the default MD3 surface token var(--md-sys-color-surface) so the blur integrates with dark mode seamlessly.
  • Keep the blur radius between 12px and 24px for optimal performance and legibility.

Don't

  • Don't remove aria-hidden="true", as the blur mask is purely decorative.
  • Don't use excessively large blur radii (> 48px) on low-end mobile devices to avoid GPU fill-rate throttling.
  • Don't apply the mask inside a container without position: relative or overflow: hidden.

Design Tokens

Color System

The mask utilizes semantic MD3 color tokens for natural background matching:

TokenCSS VariablePurpose
Surface--md-sys-color-surfaceDefault surface tint background
Surface Container--md-sys-color-surface-containerCard and modal dialog backdrop tint
Surface Container Low--md-sys-color-surface-container-lowFlat surface overlays

Blur & Motion Tokens

PropertyDefault ValueRecommended Range
Default Blur12px8px – 24px
App Bar Preset16px12px – 20px
Reduced Motion Blur0pxAutomatically applied

Accessibility

  • Decorative Element: Built with aria-hidden="true", preventing screen readers from announcing empty presentation elements.
  • Event Transparency: Has pointer-events: none, allowing touch, click, and scroll events to pass directly through to underlying elements.
  • Prefers Reduced Motion: Automatically zeroes the backdrop blur when the user has requested reduced motion.

API Reference

FadingBlurMask

The primary primitive component.

PropTypeDefaultDescription
direction"top" | "bottom" | "both""top"Gradient fade direction.
blurIntensitynumber12Backdrop blur radius in pixels.
blurHeightnumber | string"100%"Height of the fade mask container or gradient zone.
colorstringvar(--md-sys-color-surface)Tint color that fades continuously with the blur.
classNamestringundefinedAdditional CSS class names.
styleReact.CSSPropertiesundefinedCustom inline styles.
childrenReactNodeundefinedOptional children rendered inside the blur mask container.

FadingBlurProps

Mixin interface integrated into MD3 Expressive App Bars (SmallAppBar, MediumFlexibleAppBar, LargeFlexibleAppBar, BottomAppBar).

PropTypeDefaultDescription
enableFadingBlurbooleanfalseEnables smooth fading edge and backdrop blur effect.
blurIntensitynumber12Custom blur intensity in pixels when active.
blurHeightnumber | stringundefinedCustom blur height. Defaults to container height.
fadingBlurColorstringApp Bar container colorCustom tint color that fades continuously with the blur.

FadingBlurDirection

Union type representing allowed gradient directions:

type FadingBlurDirection = "top" | "bottom" | "both";