Viewport units.

120 views

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 */
}

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 */
}

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 */
}

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 */
}

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 🔗

chromeedgefirefoxsafari
10810810115.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 */
    }
}

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!