DEV Community

Leonardo Muniz
Leonardo Muniz

Posted on • Updated on

[EN] Viewport units in CSS: Beyond VH

Well, this text comes from someone who's just discovered something and wants to tell the whole world about it. Up until a few hours ago, I didn't know there were other viewport units besides vh/vw. how did I notice that?? By facing responsiveness issues and searching for solutions. I had implemented a modal that needed to take up 100% of the page height. So '100vh' worked pretty well... on desktop. The real problem emerged when I tested it on a mobile device. Below, I explain the problem and how I solved it.

In this article, I'll try to discuss the 'new' CSS viewport units: svh, lvh, and dvh. But first, let's understand a few basics before we delve deeper.

Summary of content

What is a Viewport? ๐Ÿ”—

In a nutshell, the viewport is the visible area of a web page on a device. The size of the viewport varies according to the device, the browser, and can even be changed by the user if they resize the browser window.

Browsers UI examples

VH โ€” Viewport Height

"VH" was introduced in CSS module 3 and is a relative CSS unit. It allows webpage elements to be sized based on the screen size, creating a responsive layout. Thus, 'vh' represents a percentage of the viewport height.

1vh=1% of the viewport height.

.foo {
height: 50vh; /* The element will be 50% of the viewport height */
}
Enter fullscreen mode Exit fullscreen mode

VH Problems ๐Ÿ”—

While 'vh' brought many improvements, especially for desktops, mobile devices posed some challenges. Some browsers have a navigation bar that occupies screen space. This bar usually overlays the webpage content and can dynamically expand or retract based on the direction the user scrolls. Therefore, 'vh' can behave unexpectedly on some devices.

Browsers UI examples

Browsers UI examples

Because of these problems, the community discussed and came up with some solutions:

SVH โ€” Small Viewport Height ๐Ÿ”—

'svh' is defined considering the viewport size when the navigation bar (or other browser items) is expanded. So when the browser occupies as much space as possible, the page content will be the smallest.

In the example below, '100svh' will occupy the screen space considering the expanded navigation bar, without content "hanging" beneath the bar.

Browsers UI examples

.container {
height: 100svh; /* The element will be the viewport height considering the expanded UI */
}
Enter fullscreen mode Exit fullscreen mode

When to use:
When you want to ensure content won't be obscured by the browser's UI.

When to avoid:
If the browser's UI is retracted, as there might be extra white space.

LVH โ€” Large Viewport Units ๐Ÿ”—

Conversely, 'lvh' is the opposite of 'svh'. It's defined considering the viewport size when the navigation bar or other browser items are retracted. Essentially, 'lvh' behaves similarly to 'vh'.

.container {
height: 100lvh; /* The element will be the viewport height considering the retracted UI */
}
Enter fullscreen mode Exit fullscreen mode

When to use:
To maximize content space when the browser's UI is retracted.

When to avoid:
If the browser's UI is expanded, as content might be obscured.

DVH โ€” Dynamic Viewport Units ๐Ÿ”—

As the name suggests, Dynamic Viewport is dynamic. It automatically adjusts the content size based on the browser's UI, whether expanded or retracted. Although this might seem perfect, one must be cautious: using 'dvh' could cause content to resize when the user scrolls, which could be distracting and degrade user experience, not to mention potential performance costs.

.container {
height: 100dvh; /* The element's height will dynamically adjust with the browser's UI */
}
Enter fullscreen mode Exit fullscreen mode

When to use:
When you want dynamic height adjustments as the browser's UI changes.

When to avoid:
If dynamic resizing could distract the user or negatively impact user experience.

Browser compatibility ๐Ÿ”—

chrome edge firefox safari
108 108 101 15.4


Progressive Enhancement ๐Ÿ”—

@supports is a conditional CSS rule that allows you to check whether or not a browser supports a certain property or value. It's very useful if you want to apply advanced or experimental styles and ensure that if the browser doesn't support it, it offers a valid alternative to the browser without harming the user experience.
This is "progressive enhancement".

Here's a basic example:

/* Standard styles for all browsers */
div {
    height: 50vh; /* using the traditional vh unit */
}

/* Specific styles for browsers that support svh */
@supports (height: 50svh) {
    div {
        height: 50svh; /* using the new svh unit */
    }
}
Enter fullscreen mode Exit fullscreen mode


This ensures that if the browser doesn't support SVH, it will use VH.

Thanks Camilo , for the wonderful suggestions for this article, you're amazing!

Top comments (5)

Collapse
 
lixeletto profile image
Camilo Micheletto

This post deserves more views, very visual and well explained.

This article would benefit from a compatibility table for each one of the units since even if they're evergreen, it's just to modern browsers.

In this article I have a suggestion of a compatibility table in markdown that might suit this case.

You can also use Bramus approach

Also, we can make use of @supports tag for progressive enhancement!

Collapse
 
leomunizq profile image
Leonardo Muniz

I followed your advice, thank you very much for your contribution, I hope you enjoy it. <3

Collapse
 
lixeletto profile image
Camilo Micheletto

It's great! I loved it

Collapse
 
mazonthemoon profile image
Mary Ronan

Great read, thanks mate ๐Ÿ‘๐Ÿ‘๐Ÿ‘

Collapse
 
leomunizq profile image
Leonardo Muniz

I'm so happy you enjoyed it ๐Ÿ˜Š