Liquid Glass, but in CSS

[ad_1]

This past week marked the start of WWDC25, Apple’s yearly developer conference where they reveal new platforms, technologies, and (most relevant here) design languages. During the presentation they released their newest iteration, dubbed Liquid Glass. I have a lot of thoughts on this new language, but my immediate thought while I was watching the presentation was “I wonder if CSS can do that”. It turns out, yes, with great effort, it can.

Liquid Glass

A note about compatibility

This effect is dependant on CSS SVG filter support, and will not function
properly in browsers other than Chrome.

Light Glass
Example

Scouring through the videos available from Apple, and by downloading the beta software myself on my devices, I was able to start breaking down some of the layers that make up the Liquid Glass effect.

Highlights on the edges of the glass help to suggest the illusion of depth, and imply the smoothness of the shape. This is important for making the element look like a physical, tactile object— rather than a flat shape on a screen. This should be the easiest element to replicate, since we can approximate a round shape fairly easily with a series of inset

box-shadow

properties.

I’m using two shadows for the top left corner, and two for the bottom left. This allows for the shadow to sharply increase in intensity as it reaches the edge of the shape, simulating the fresnel effect.
This one’s easy, we can use the

filter

prop to apply effects onto our dom element. In this case though, we want to apply the effect to the content behind our element, rather than the element itself— so we’ll need to use the

backdrop-filter

instead.

😀😃😄😁😆😅😂🤣🥲🥹☺️😊

The Liquid Glass demos all show the material adjusting the color that passes through it, specifically decreasing the contrast, and boosting saturation. This has the effect of making anything behind the glass look more vibrant. We can use the same technique as above to adjust the color of light that passes through the glass.

😀😃😄😁😆😅😂🤣🥲🥹☺️😊

Next, we need to simulate the way that round pieces of glass warp light that passes through them. This layer also marks the first time we need to distort content underneath the glass, rather than just painting over top of it. To accomplish this, we can use the

filter

CSS property in conjunction with an SVG filter injected alongside the component. This filter will consist of a number of stages that all build on each other to create a cohesive refraction effect.

To distort the objects under our shape, we’ll need to generate a distortion map. This will tell the browser how much to move each pixel when performing the distortion. In our case, we want to bulge out all the pixels towards the center of our panel, and squish them towards the edges. Let’s start by generating a blank distortion map that we can build off of as an SVG.

The final result is a gradient going from 0-1 in the red channel
horizontally, and 0-1 in the blue channel vertically. You can think of each
pixel having an X and Y coordinate for where it’s supposed to go in the
final image. Right now, everything is lined up, meaning the pixel in the
dead center of the image has an XY value of (0.5, 0.5), meaning that it
would not be moved at all. But we can influence these colors to be different
from their location in the image, to tell the browser where each source
pixel should be moved.

Now that we’ve generated this base map (normally called an “identity map” in
graphics lingo), we can use normal SVG shapes and blend modes to adjust the
color of parts of the map. In this case, we want to make the XY values rise
slower towards the center, and more sharply towards the edges.

To achieve the stretch we’re looking for, we can simply adjust the gradient
ramp to compress the space around the edges. In this example, we’re
effectively squishing 30% of the vertical and horizontal frame into just 5%
of the space on each edge.

To use our new SVG as a distortion map, we’ll need to first convert it to a data url, to let us use it in the

element. To do this, we can write a simple helper function to convert our HTML into a URI-encoded string, and prepend the data url prefix.

Now that we’ve got our string, we can start to build an SVG effect chain. We’ll make our filter 40 pixels larger than our target element, and offset it by -20 pixels to allow our effect to overhang our target element, which allows the distortion have some extra room before clipping the edge of our shape.

Next, we’ll want to simulate the ripple distortion present in larger pieces of glass. This is fairly straightforward, and the SVG filter spec already has a basic turbulence texture built in, so we can plug that into another

layer, just as before.

Lastly, we’ll want to simulate the chromatic aberration of light as it passes through our element. This is when some colors of light travel further than others. There’s no simple way to do this with SVG filters, but what we can do is take three copies of our existing image, filter out different colors for each copy, offset them by different amounts, and blend them back together.

Now that we’ve created all our effects, we can layer them in the SVG filter, and apply them via the

filter: url(#filterId);

syntax to apply them to a DOM element— and that’s it! We’ve successfully created a take on liquid glass. This approach isn’t fully cross-browser, which is unfortunate.

After much effort, I’ve not found a way to recreate this effect in Safari/Firefox. For now, you must remove the SVG filter from the

filter

CSS prop from the filter chain in these browsers, leaving just the blur effect, and the drop shadows. This is a reasonable fallback, and shouldn’t fundamentally break any UI, but it’s not ideal.

This approach also takes a non-insignificant amount of GPU brunt, and more than one or two glass elements can quickly slow the tab down— especially if they animate in any way. Glass elements are (currently) only really viable for hero/feature elements, rather than a full UI.

Most of the approach described in this article were built directly overtop of the methods described in the excellent Smashing Magazine article “A Deep Dive Into The Wonderful World Of SVG Displacement Filtering”.

The Apple Liquid Glass documentation was also excellent for describing the basic components of the effect, and some considerations for usage. It’s definitely worth a quick read.

Pup Atlas!

[ad_2]

Share this content:

I am a passionate blogger with extensive experience in web design. As a seasoned YouTube SEO expert, I have helped numerous creators optimize their content for maximum visibility.

Leave a Comment