Chrome and Firefox don't support viewport units on iOS
Photo by Lena Polishko

Chrome and Firefox don't support viewport units on iOS

January 30, 2024

If you’re among the 12% of iOS users who don’t use Safari, cover images on this website might look strange when you scroll. For everyone else (and desktop readers), take a look at how the flower photo stretches and compresses on Chrome and Firefox but stays the same size on Safari:

The image behaves like this because I’m defining its height in terms of svh (small viewport height) units, which are supposed to be proportional to the browser’s content area when all of the toolbars are visible (also known as the “small viewport”). When I make the image 75svh tall, it should take up exactly 75% of the small viewport. I do this to make sure that even when the content is at its smallest, the cover image will still be just short enough that you can see the post title. The problem is that on Chrome and Firefox, the svh unit is acting like the dvh (dynamic viewport height) unit which is proportional to the current viewport. This means that when the viewport gets bigger as you scroll down (since the toolbars go away), each unit counts as slightly more pixels and the cover image expands.

This is an unusual issue because in theory, it should be impossible. CSS feature support is determined by browser engines which handle layout and styling for browsers. All browsers sharing an engine should also share the same level of CSS functionality; for example, if Google decided to implement the new masonry layout in their Blink engine, all of the browsers using Blink like Edge, Opera, and Brave, as well as Chrome would get masonry layout support “for free” when they update to the latest version of Blink. On iOS, all browsers are required to use Apple’s Webkit browser engine so there shouldn’t be this descrepancy where svh works on Safari but doesn’t work on Chrome and Firefox. Even caniuse.com, a highly trusted source for browser feature compatability, claims that svh is supported by every iOS browser since “all iOS browsers use the same version of Webkit”. However, the unit is obviously still broken; so, what’s the explanation for this glitchy behavior?

As far as I can tell, the fault lies with Google and Mozilla. Two years ago, around the time Apple shipped viewport units for Webkit, they added the minimumViewportInset and maximumViewportInset APIs to Webkit so that third-party browser developers could support these new units. These APIs are dead simple—all you have to do is set the size of the viewport at its smallest and at its largest and this enables Webkit to properly define the small and large viewport for units like svh. However, neither Google nor Mozilla added the two lines of code needed to make these units work. So, svh, alongside a host of other viewport units like lvh have been unsupported on Chrome and Firefox for the last two years without any documentation.

With this being said, there’s not much to be done from the web developer’s perspective. Since Chrome and Firefox use Webkit, there’s no way to detect them through the user-agent and replace viewport units with something like pixels. It’s not even possible to fallback to another unit since these viewport units are technically supported, they just reference the wrong values. So, it’s either deal with the lack of support or don’t use viewport units anywhere—I’m just going to use them because it looks nice on my phone and my friends’ phones but for much bigger websites, there might be a conversation worth having.

Edit: I attempted to fix this issue for Firefox on my own since it’s open source, and it seems much harder than I initially thought. After doing what I outlined above, here’s what it looks like:

Obviously, the problem isn’t fixed. The problem is that the toolbar shrinking/growing is implemented by making the entire viewport grow/shrink in the opposite direction. This means that fixing this issue requires a bespoke implementation of the viewport units or a rewrite of the various UI components involved in this, which I don’t want to wade into as someone new to the project. Lesson learned: things are actually much more complicated than I think and I shouldn’t be such a naive and confident fool >__<.