A liquid-glass button, and the @property trick behind it
Petr Knoll's glass button has been making the rounds, and it's worth pulling apart, because almost every effect in it is a trick worth keeping. Hover and press it (it sits on a light, dotted panel so the frosting has something to blur):
The frost
The pill is translucent with a backdrop-filter: blur, so it genuinely frosts
whatever sits behind it. That's the part that makes it read as glass and not
just a light gradient, and it's why it needs a busy background to show off. Two
inset shadows finish the edge: a soft dark one up top, a brighter one along the
bottom, like light catching the lower rim.
.glass-btn {
backdrop-filter: blur(clamp(1px, .125em, 4px));
box-shadow:
inset 0 .125em .125em rgba(0,0,0,.05),
inset 0 -.125em .125em rgba(255,255,255,.5),
0 .25em .125em -.125em rgba(0,0,0,.2);
}The @property trick
Here's the clever bit. CSS won't animate the angle inside a gradient. The angle is part of an unparsed value, so the browser has nothing to interpolate. Registering the angle as a real typed custom property fixes that:
@property --glass-1 {
syntax: "<angle>";
inherits: false;
initial-value: -75deg;
}Now --glass-1 is an actual angle the browser can tween. The button's border is
a conic-gradient(from var(--glass-1) …) masked down to a hairline with
mask-composite: exclude, and a second registered angle drives a diagonal sheen
that slides across the face. On hover and press, both angles transition, so the
light appears to sweep around the glass instead of snapping.
The little touches
A separate blurred element under the button is the shadow, and it shifts as you
interact, so the button feels like it lifts on hover. On :active the whole
wrap tilts back with rotate3d(1, 0, 0, 25deg), a tiny bit of physicality that
makes the press land. Everything is em-based, so it scales with font-size, and
the angle animations quietly freeze on touch devices rather than jumping.
Full credit to Petr Knoll. Grab the component on the Liquid Glass Button page.
Ask your agent to implement this
Read the full writeup at https://seangeng.com/writing/a-liquid-glass-button.md and implement it in my project.
It covers: A liquid-glass button, and the @property trick behind it — Petr Knoll's frosted glass button, ported to a component. backdrop-filter for the frost, layered inset rims, and an animated conic-gradient border + sheen powered by @property angle interpolation.
Requirements:
- Follow the technique/approach exactly as described in the writeup.
- Adapt names, colors, and styling to my project's existing conventions.
- If it's a component, make it reusable with sensible props and TypeScript types.
- Keep it accessible: semantic HTML, keyboard support, and respect prefers-reduced-motion.
- When done, tell me which files you created or changed and how to use it.Paste into Claude Code, Codex, Cursor, or any agent. view raw .md