Floating surfaces can show the page behind them through a frosted, translucent container. The effect is off by default. One custom property turns it on for a page or a region, without JavaScript.
The three toolbars differ only in their wrapper's settings: off, the defaults, and a 4px blur at 40% opacity. Glass frosts whatever sits behind a surface. Over a flat page color it looks almost solid, so the demos sit on a striped backdrop.
Turn it on
Set --expressive-glass: true on :root to turn it on for the whole page:
:root {
--expressive-glass: true;
}
Or set it on an element that contains the surfaces to turn it on for that
region only. --expressive-glass: false turns it off again
inside a region.
<main style="--expressive-glass: true">
<div class="toolbar">...</div> <!-- glass -->
<section style="--expressive-glass: false">
<div class="toolbar">...</div> <!-- solid -->
</section>
</main>
The browser reads the value from the surface's parent, so setting
--expressive-glass on the surface itself has no effect. Put it on
:root or on a wrapper.
Settings
Three custom properties control the effect. Each works on :root or on a wrapper, and the closest one wins.
| Property | Default | Effect |
|---|---|---|
--expressive-glass | unset (off) | true turns glass on and false turns it off. In the default build, only true turns it on. |
--expressive-glass-blur | 16px | Blur radius of the backdrop. Higher values frost more. |
--expressive-glass-opacity | 72% | How much of the surface color stays. 100% is solid, and lower values let more of the page through. Use a percentage. |
:root {
--expressive-glass: true;
--expressive-glass-blur: 16px; /* frost thickness */
--expressive-glass-opacity: 72%; /* share of the surface color kept; 100% is solid */
}
Each surface mixes its own container color with transparency, so theme and component color tokens still apply.
Sass defaults
Sass builds can turn glass on by default and change the default blur and opacity. The custom properties still override these settings at runtime.
| Variable | Default | Effect |
|---|---|---|
$expressive-glass | false | true makes glass the default, and only --expressive-glass: false turns it off. |
$expressive-glass-blur | 16px | Fallback for --expressive-glass-blur. |
$expressive-glass-opacity | 72% | Fallback for --expressive-glass-opacity. The build fails if it is not a percentage. |
@use "@expressivecss/expressive/src/sass/expressive" with (
$expressive-glass: true,
$expressive-glass-blur: 16px,
$expressive-glass-opacity: 72%
);
Surfaces
The effect applies to these surfaces:
- Menus, tooltips and popovers
- Dialogs, the command palette, bottom sheets and side sheets
- The snackbar
- The navigation bar and navigation rail
- Toolbars and the search view
Grouped menus and a modal navigation rail keep a solid surface. The modal rail would otherwise clip its own scrim.
Accessibility
Users who ask for reduced transparency or more contrast in their system
settings see solid surfaces. The framework checks
prefers-reduced-transparency: reduce and
prefers-contrast: more, so you do not need to.
Text on a glass surface sits over whatever the page shows behind it. Over
busy images or saturated colors, keep --expressive-glass-opacity
high enough that labels still meet contrast requirements.
Caveats
- The switch uses CSS style queries. Browsers without them show solid surfaces.
-
backdrop-filtermakes a surface the containing block for itsposition: fixeddescendants. A fixed element inside a glass surface is placed relative to the surface, not the viewport.
Preview this site
The Frosted glass button in this site's app bar sets
--expressive-glass: true on :root for every page.
It also tints the page background so the effect shows behind the
surfaces. The choice is saved in this browser.