Liquid Glass
An optional liquid-glass extension for the Cupertino theme. Adds glass surfaces in four levels, from clear to opaque, and a refraction effect to any element through CSS classes.
The demos on this page only render as glass under the Cupertino Glass theme. Pick it from the theme switcher in the bottom-left corner, and note that the entry is Cupertino Glass — the plain Cupertino entry is a different theme and cannot show the effect. Under every other theme the cards below render as ordinary opaque cards. That is the page, not your browser.
Installation
php artisan wirekit:glass install
This publishes two files to public/:
wirekit-glass.— glass class definitionscss wirekit-glass.— setsjs wk-glass-tier2on<html>where the browser accepts an SVG filter throughfilter. The refraction is gated on that class, so without the script.wk-glass-refractstays the Tier 1 glass surface
Then add the component as the first element in your layout's <body>:
<head>
@wirekitStyles
</head>
<body>
{{-- FIRST thing in the body, never in the head: this emits an <svg>, and an SVG in
the head ends head parsing — every metadata tag after it is reparented into the
body, where a crawler does not look. --}}
<x-wirekit::glass />
{{-- … your layout … --}}
@wirekitScripts
</body>
The <x-wirekit:: component loads the CSS, JS, and injects the SVG filter definition needed for Tier 2 refraction.
Tier 1 — Glass
The .wk-glass class makes an element liquid glass: a light backdrop-filter blur, a thin fill, and an edge that catches the light. It works in every supported browser, at the regular level unless a level says otherwise.
wk-glass class. The gradient comes through the glass, the dotted pattern softens behind it, and the edge catches the light.
<x-wirekit::card class="wk-glass">
<x-wirekit::card.header>Glass</x-wirekit::card.header>
<x-wirekit::card.body>
Content here.
</x-wirekit::card.body>
</x-wirekit::card>
Levels
A level class sets how much of the backdrop the glass shows. Put it on the glass element itself, or on any ancestor, such as <html> for a whole application:
| Class | Shows of the backdrop | Use it for |
|---|---|---|
wk-glass-clear |
the most: it softens, its detail stays | controls over photos, video or strong color |
wk-glass-regular |
some: color and shape come through | the default; floating bars, menus and cards over color |
wk-glass-frosted |
little: a milky pane | panels full of text, and anything over busy content |
wk-glass-opaque |
nothing: the theme's elevated surface | an in-app setting for readers who want no transparency |
With levels nested in each other, the nearest one decides the colors and the blur comes from the level defined later in the stylesheet, so write the level on the glass element itself where a level sits inside another.
Tier 2 — Refraction Glass
The .wk-glass-refract class renders clear refracting glass rather than frosted glass with an effect added — an SVG fe bends the backdrop the way a textured pane does, so what is behind the surface stays visible and comes through distorted. A thin blur and a thin wash are deliberate here: the refraction can only bend a backdrop that still reaches the eye. The distortion sits on a layer behind the content, so the surface's own text stays perfectly legible.
Pick it when the backdrop itself should bend. Pick wk-glass when the content on top needs a calmer surface: its levels decide how much of the backdrop shows, and wk-glass-frosted hides most of it. One further difference matters at the call site: a refracting surface clips anything overflowing it, so it is not the right host for a dropdown or a tooltip.
The bending needs Chromium. Every browser on an iPhone or iPad runs Safari's engine, which accepts the filter and paints nothing from it, so there a refracting surface shows as clear glass under a light frost.
<x-wirekit::card class="wk-glass-refract">
<x-wirekit::card.header>Refraction Glass</x-wirekit::card.header>
<x-wirekit::card.body>
Content here.
</x-wirekit::card.body>
</x-wirekit::card>
Side-by-Side Comparison
wk-glass — all browsers. The dots soften behind the glass.
wk-glass-refract — dots distort organically behind the glass.
With Other Components
Glass classes work on any element. Here are examples with different WireKit components:
Dark Mode
Glass follows dark mode on its own. Under a .dark ancestor every level takes darker values from the same tokens: a dark fill, a dimmer rim, and an edge that keeps a softer light.
How It Works
Tier 1 — Glass (all browsers)
.wk-glass {
backdrop-filter: blur(6px) saturate(1.6) brightness(1.04);
background: var(--glass-wk-fill);
border: 1px solid var(--glass-wk-rim);
box-shadow:
inset 2px -2px 1px -1px var(--glass-wk-highlight),
inset -2px 2px 1px -1px var(--glass-wk-highlight),
inset 6px -6px 1px -6px var(--glass-wk-sheen),
inset -6px 6px 1px -6px var(--glass-wk-sheen),
inset 0 0 2px var(--glass-wk-edge),
var(--glass-wk-shadow);
}
The blur and the fill decide how much of the backdrop shows, and each level sets both. The edge decides whether the pane reads as glass: two bright inner lines on opposite corners, a softer light inside them, a dark hairline around the pane, and the shadow it casts.
Tier 2 — SVG Refraction
.wk-glass-refract {
/* 1. Clips the overshooting layer below back to a straight edge. */
overflow: hidden;
isolation: isolate;
background: transparent;
}
.wk-glass-refract::before {
/* 2. A layer BEHIND the content carries the backdrop, so the distortion
lands on the background and the card's own text stays sharp. */
content: '';
position: absolute;
inset: -40px; /* 3. Overshoots — see below. */
z-index: -1;
background: rgba(255, 255, 255, 0.22);
backdrop-filter: blur(3px) saturate(1.6) brightness(1.03);
filter: url(#wk-glass-refract); /* 4. feTurbulence + feDisplacementMap. */
}
Two details in there are load-bearing, and both are easy to undo by accident.
Tier 2 is a different material, not Tier 1 with an effect on top. Its layer keeps its own thin blur and wash, whatever level surrounds it. Frosting removes the structure behind a pane, and a refraction can only bend structure that still arrives: raise the blur to the frosted level's and the distortion has nothing left to work on, so the effect disappears while every declaration stays valid.
The layer overshoots and the element clips it. The displacement moves that
layer's own edge along with everything else, so a layer sized exactly to the card
would give the card a rippling outline. Overshooting pushes the rippled edge
outside, and overflow: hidden brings a straight one back. The cost: a Tier 2
surface clips its descendants, so it cannot host a dropdown or tooltip that
overflows it. Tier 1 has no such restriction and stays the default.
Detection Script
The included JS detects Tier 2 support and adds wk-glass-tier2 to <html>:
// Debug mode: add ?wk-glass-debug to your URL
// Console output: [WireKit Glass] Tier: 2 (Refraction) | UA: ...
CSS Classes
| Class | Tier | Browsers | Effect |
|---|---|---|---|
wk-glass |
1 | All modern | Liquid glass at the regular level: a light blur, a thin fill and an edge that catches the light. |
wk-glass-clear, wk-glass-regular, wk-glass-frosted, wk-glass-opaque |
1 | All modern | The level, on the glass element or on any ancestor: from the clearest pane to the theme's opaque surface. |
wk-glass-refract |
2 | Chromium bends the backdrop; Safari shows it lightly frosted, without the bending | Clear refracting glass — the backdrop stays visible and bends. Clips its own overflow. |
HTML Classes (set by JS)
| Class | Set on | Meaning |
|---|---|---|
wk-glass-tier2 |
<html> |
Browser accepts an SVG filter through filter. The refraction is gated on it: without it, .wk-glass-refract is the Tier 1 glass surface. You can style on it too |
Accessibility
-
prefers-reduced-transparency: reduceremoves the blur entirely and makes every level the theme's opaque surface. macOS "Reduce transparency" and Windows "Transparency effects: off" both set it, and both are switched on for the same reasons: text over a moving, low-contrast backdrop is hard to read, and for some readers the shifting background is a vestibular trigger. The blur is removed rather than weakened, because a weaker blur is still a blur. Safari does not report this setting to a page, so on Apple devices it does not reach the glass; offerwk-glass-opaqueon<html>as an in-app setting for readers who want it. -
prefers-contrast: moregives an opaque pane with a strong border. Apple's "Increase Contrast" sets it, and Safari reports it, so this is the one Apple accessibility setting the glass answers on its own. -
forced-colors: activehands the surface to the system. In High Contrast mode the OS replaces colors outright, and abackdrop-filtersurvives that replacement — so without this the blur would keep painting under text the system had just recolored for contrast, which is the exact combination the mode exists to prevent. The panel becomesCanvas/CanvasTextlike every other panel in that mode, and its shadow goes with it: a shadow is not recolored either, and survives as a stray smudge around an otherwise flattened panel. -
On paper the panel keeps a boundary and nothing else.
backdrop-filterdoes not paint in paged media at all, and the material is built from a translucent white fill and border. Browsers drop background graphics when printing unless the reader turns them on, so both would vanish and the content the surface was grouping would print as loose text with nothing around it. The print rule replaces them with a singlecurrentColorborder, which prints because the text prints. -
Glass effects are purely decorative — no impact on screen readers
-
Text on glass surfaces must still meet WCAG 2.2 contrast requirements (4.5:1 for normal text, 3:1 for large text)
-
On the regular, frosted and opaque levels, WireKit's default text holds 4.5:1 over the backdrop of the first demo on this page, in light and dark. The clear level shows the most of what is behind it, so keep its text short and bold, or dim a bright backdrop under it
-
Reduced motion: the animated gradient backgrounds on this page respect
prefers-reduced-motion: reduce— the animation pauses automatically for users who prefer reduced motion
Keyboard Interaction
This component is purely presentational and does not respond to keyboard input.
Design Tokens
The glass stylesheet declares six custom properties of its own. Each level sets all six, for light and for dark:
| Token | Colors |
|---|---|
--glass-wk-fill |
the tint laid over the blurred backdrop |
--glass-wk-rim |
the border |
--glass-wk-highlight |
the bright inner edge, top-right and bottom-left |
--glass-wk-sheen |
the softer light just inside it |
--glass-wk-edge |
the dark hairline that gives the pane its thickness |
--glass-wk-shadow |
the shadow the pane casts |
The opaque level reads the theme's --color-wk-bg-elevated and --color-wk-border, so it follows every preset. Text on glass inherits the standard text tokens (--color-wk-text, --color-wk-text-muted). The demos on this page draw their backdrop through --glass-demo-gradient, a property of this page's own style block, not of the extension.
Customization
Pick a level first. For values of your own, set the tokens in your own stylesheet: on :root for the default level, under .dark for dark mode, or on a level class for that level. They survive a reinstall of the published file, which an edit to it does not:
/* A warmer, slightly milkier default glass. */
:root {
--glass-wk-fill: rgb(255 248 240 / 0.3);
}
.dark {
--glass-wk-fill: rgb(40 32 24 / 0.45);
}
The blur belongs to the level and is not a token: some Safari releases drop a backdrop-filter built from a custom property, which would leave the fill without its blur. Each level sets it to:
| Level | Blur | Fill, light / dark |
|---|---|---|
| clear | blur(2px) saturate(1.4) |
5% white / 16% near-black |
| regular | blur(6px) saturate(1.6) brightness(1.04) |
20% white / 40% near-black |
| frosted | blur(20px) saturate(1.8) brightness(1.05) |
72% white / 78% near-black |
| opaque | none | --color-wk-bg-elevated |
The refraction's strength is the scale of the fe in the component, 60: higher bends more.
php artisan wirekit:glass install skips a published file that differs from the package copy, because it may carry your edits, so after an update that changes the glass, run it with --force once your own values live in your stylesheet.
Usage & Conventions
Browser support: Tier 1 (glass via backdrop-filter, at every level) works in every supported browser. Tier 2 bends the backdrop with an SVG fe in Chromium-based browsers such as Chrome and Edge. Safari, and every browser on iPhone and iPad, accepts the filter and paints no displacement from it, so .wk-glass-refract shows there as clear glass under a light frost, without the bending.