Liquid Glass Spikes

Here are a set of demos used to experiment with how Safari 26 with Liquid Glass works with various CSS.

In particular, we noticed that modals behave in unexpected ways with the new floating UI design for the Safari toolbar.

Table of contents

Summary of findings

The conditions for a fullscreen modal overlay element to cover the entire screen with a position: fixed; seems to be:

This also means the standard <Dialog> and ::backdrop don't seem to work.

The conditions for a bottom sheet to cover the entire screen, including the area around the Safari toolbar seems to be:

Issues in production

Here are some examples of sites that break with Safari 26.

Apple.com/iphone

Link

Opening one of the modals causes the overlay to appear, but as the overlay can not reach the bottom of the viewport, you can still see some content from the underlying page around teh afari liquid glass toolbar. This can include words, images and in some cases playing videos.

apple.com/iphone with a collapsed Safari toolbar apple.com/iphone with an expanded Safari toolbar
Link

Start by doing a search, then click on one of the search results. This opens a full screen modal showing related images, but as the overlay can not reach the bottom of the viewport, the initial search results are visible around the Safari liquid glass toolbar.

Update: This seems to behave differently now (first screnshot is before, second is after), not sure if Google or Safari changed.

Google image search showing an image modal - before change Google image search showing an image modal- after change

Demonstration of specific issues

Here are some specific demos that were made while trying to work out how to control what is displayed around the liquid glass toolbar.

Native <Dialog> element

Demo

This example has minimal implementation logic and relies on Safari's own implementation of the <Dialog> component, which includes a subtle backdrop color for the overlay.

However, the overlay does not extend to the top and bottom of the viewport as one would expect and instead stops short at the top and bottom of the "safe area".

Native dialog element with a subtle backdrop

Overlay color

Demo

This is a small, custom implementation of a modal dialog and bottom sheet with various colors set for the overlay.

The color choice seems to affect whether or not the modal reaches the ends of the viewport. A solid color or linear gradient does not go to the far edges of the viewport, while a semi-transparent color does.

The other thing to note with this example is that when the bottom sheet is displayed, it will fill in the bottom area of the viewport around the Safari toolbar, but this isn't the case for a lot of websites, including our "sticky bottom" on realestate.com.au

Overlay color — linear gradient (dialog) Overlay color — linear gradient (sheet) Overlay color — semi-transparent (dialog) Overlay color — semi-transparent (sheet) Overlay color — solid (dialog) Overlay color — solid (sheet)

safe-area-inset-bottom

Demo

Chrome on Android handle a similar thing with the operating systems gesture bar covering the content at the bottom of the viewport. There is a blog post explaining how to use env(safe-area-inset-bottom) variable to cater for this, along with the use of the viewport-fit=cover option in the viewport meta tag to control this behaviour.

While we couldn't find the equivalent documentation for Safari, according to caniuse.com, Safari do support most of the same features as Chrome, however they do not seem to take effect for the Safari UI.

In this demo, there is supposed to be a red square with the height and width of the env(safe-area-inset-bottom) variable and while it's visible on chrome when there is content overlapping with floating UI from Android, it is not visible on Safari which would indicate that variable is not populated with a value in this case.

safe-area-inset-bottom demo on Safari safe-area-inset-bottom demo: Safari vs Android

vh units

Demo

Another way of controlling the height of elements is with the various viewport units. While vh has historically caused lots of issues on mobile browsers, the introduction of dvh, svh and lvh have helped to address some of these issues.

However, even when using viewport units that are supposed to extend past any dynamic toolbars, they still do not go into the area around the Safari toolbar and act the same as the demo with the overlay colors.

vh units — gradient 100dvh vh units — gradient 100lvh vh units — gradient 100vh vh units — semi-transparent 100dvh vh units — semi-transparent 100lvh vh units — semi-transparent 100vh vh units — solid 100dvh vh units — solid 100lvh vh units — solid 100vh

outerHeight vs innerHeight

Demo

Another way of controlling the height of elements is with JavaScript, which has properties on the window object that provide the height of the viewport both within and outside of the browser UI via window.innerHeight and window.outerHeight.

This demo shows a few variations of each of these properties, the first is with a coloured <div> within the flow of the document, which demostrates that outerHeight is the height of the entire viewport and innerHeight is the "safe area" in between the browser toolbars.

As the "safe area" between the browser UI elements is dynamic based on if the Safari toolbar is expanded or not, you can click the divs to refresh the values they are displaying but even though the values are changing, the behaviour of the modal overlays are the same.

The second thing this shows is using those same values except as a position: fixed overlay with various background colors set.

While the value of window.innerHeight and window.outerHeight seem to be set correctly as shown by the colored divs on the page, the overlay doesn't seem to be able to take advantage of them as the color of the background seems to have more of an impact on the actual height.

js innerHeight — collapsed js innerHeight — expanded js outerHeight — collapsed js outerHeight — expanded js innerHeight — semi-transparent overlay js innerHeight — solid overlay js outerHeight — semi-transparent overlay js outerHeight — solid overlay

Parent-child vs sibling relationships

Demo

The "Overlay color" demo showed that by having a semi-transparent overlay, Safari would fill the rest of the viewport with it, but not if it was a solid color or a gradient. However, the Construct Kit modal also uses a semi-transparent color but was not filling around the rest of the viewport.

The difference between them is how the elements are structured. The demo above puts the overlay and the dialog on the page as siblings while Construct Kit uses the React Modal library, which puts the dialog (or any provided content) within the overlay element as a child, rather than as a sibling.

So this means that if the overlay has any content, whether it be a white colored div or just some text, it will not fill the rest of the viewport.

Overlay as child — dialog Overlay as child — sheet Overlay as sibling — dialog Overlay as sibling — sheet

Bottom sheet height

Demo

The bottom sheet will fill the bottom of the viewport when it's height is below a certain threshold and it's positioned "close enough" (usually within around 3px or so. The actual height threshold doesn't seem to be a fixed number and I haven't worked out exactly what the conditions are here yet.

Bottom sheet height: 70vh; bottom: 0; Bottom sheet height: 60vh; bottom: 0; Bottom sheet height: 60vh; bottom: 3px; Bottom sheet height: 60vh; bottom: 4px;