DEV Community

Cover image for Building Responsive Design Using Viewport CSS Units
Anton Martyniuk
Anton Martyniuk

Posted on • Originally published at antondevtips.com

Building Responsive Design Using Viewport CSS Units

Introduction

Responsive design ensures that web content looks good and functions well, no matter the screen size.
Such design is a must-have in modern web applications.
One of the various tools in achieving responsive design is through the use of viewport units: vw, vh, vmin, vmax, vi, vb, s, l, d and their combinations.
Overall there are 24 viewport units. This blog post explains how and when to use these units to create adaptive designs.

What are Viewport Units in CSS

Viewport unit in CSS is a percentage of a screen size available in the web browser for rendering content.
Viewports offer a fluid approach to sizing elements, fonts, and spacing, unlike pixels that remain constant regardless of screen size.

The most common viewport units are: vw and vh:

  • vw (viewport width) equals 1% of the viewport's width
  • vh (viewport height) equals 1% of the viewport's height

When using pixels to create a header element, it has constant height on different screen sizes:

header {
    width: 100%;
    height: 100px;
}
Enter fullscreen mode Exit fullscreen mode

Let's make our header more responsive by giving it dynamic height of 10vh. Based on a screen size the header will always take 10% of the screen's size:

<style>
    header {
        width: 100%;
        height: 10vh;
        text-align: center;
        background-color: #9089fc;
    }

    main {
        width: 100vw;
        height: 80vh;
        margin-top: 10vh;
        background-color: bisque;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
    }
</style>

<body>
    <header>Header here</header>
    <main>Content here</main>
</body>
Enter fullscreen mode Exit fullscreen mode

Screenshot_1

Wait, we have a percentage % unit in CSS and in the following example it makes a header to take a full width of the screen.
How is it different from vw and vh ? Percentage units are based on the size of the parent element, while viewport units are always based on the size of the main viewport (screen).

Using vw, vh Viewport Units

Let's explore few examples on how to build responsive design using vw and vh:

Create a full-screen section with background image that adjusts to the height and width of the viewport:

main {
  width: 100vw;
  height: 100vh;
  background: url("background-image.png") no-repeat center center;
  background-size: cover;
}
Enter fullscreen mode Exit fullscreen mode

Space the elements relative to the viewport size to create a more adaptive layout:

.container {
  padding: 5vh 5vw;
}
.section {
  margin-bottom: 2vh;
}
Enter fullscreen mode Exit fullscreen mode

Adjust font sizes using viewport units to ensure text remains proportionate across devices, it's tempting to do as follows:

body {
  font-size: 2vw;
}
Enter fullscreen mode Exit fullscreen mode

However using only vw for font sizes can lead to extremely small or large text on very small or very large screen.
A common practice is to combine viewport units with clamp() function to set a minimum and maximum font size:

body {
  font-size: clamp(16px, 2vw, 24px);
}
Enter fullscreen mode Exit fullscreen mode

The clamp() function is used to dynamically adjust the font-size of the body element, with three parameters being passed:

  1. Minimum value: 16px - This is the smallest size the font will be. No matter how small the viewport gets, the font size won't go below 16 pixels.
  2. Preferred value: 2vw - This value allows the font size to grow and shrink dynamically with the viewport width. 2vw means 2% of the viewport width, making the font size responsive to the width of the screen.
  3. Maximum value: 24px - This is the largest size the font will be. Even if the viewport width becomes very large, the font size will not exceed 24 pixels.

Using vmin, vmax Viewport Units

vmin and vmax are viewport units that represent the viewport's smallest and largest dimensions, respectively.

  • vmin: 1vmin is equal to 1% of the viewport's smaller dimension, either width or height. It's incredibly useful for creating responsive elements based on the smallest available space.
  • vmax: 1vmax corresponds to 1% of the viewport's larger dimension. It's useful for designs that should scale aggressively in large viewports but need to be constrained in smaller ones.

vmin and vmax can be used to create a content that takes a full width or height of the screen, depending what the smaller value is.

The following CSS will create a square panel equal to the full size of the smallest viewport dimension:

<style>
    main {
        width: 100vmin;
        height: 100vmin;
        background-color: #ffa33d;
    }
</style>

<body>
    <main></main>
</body>
Enter fullscreen mode Exit fullscreen mode

On a mobile device with screen size of 360x740 this panel will take full width and have height=360px.

Screenshot_2

In landscape mode the panel will take the full height and have width=360px.

Screenshot_3

Using vi, vb Viewport Units

Imagine you're holding mobile phone in a vertical mode. When you turn it into landscape mode - the screen image rotates and the phone is in horizontal mode.

  • vi: This is Viewport inline. 1vi is 1% of the viewport's width in horizontal writing modes and 1% of its height in vertical modes.
  • vb: This is Viewport block. 1vb is 1% of the viewport's height in horizontal writing modes and its width in vertical writing modes.

You can create two CSS classes to define adaptive design in horizontal and vertical modes.
In horizontal (landscape) mode it scales horizontally: the wider the screen, the wider the block is.
In vertical mode it scales vertically: the higher the screen, the higher the block is.

<style>
.container-horizontal {
    width: 50vi; /* Equals to 50vw */
    height: 50vi;
    background-color: beige;
}

.container-vertical {
    width: 50vb;
    height: 50vb; /* Equals to 50vh */
    background-color: darkseagreen;
}
</style>

<body>
    <div class="container-horizontal"></div>
    <div class="container-vertical"></div>
</body>
Enter fullscreen mode Exit fullscreen mode

Here, horizontal container has square size of 50% of the screen's width everytime and its height is varying depending if the screen has horizontal or vertical mode.

Screenshot_4

Vertical container has square size of 50% of the screen's height everytime and its width is varying depending if the screen has horizontal or vertical mode.

Screenshot_5

Using s, l, d Viewport Modifiers

So far we have learned 6 viewport CSS units. Explored viewport units work only for a static viewport size and they can't handle use cases when a viewport size is changing.
A perfect example for such a use case is again a mobile phone. Have you ever noticed URL bar disappearing when you're scrolling down the page in the mobile' browser? And it gets back when you scroll up.
The viewport's size is changing depending on whether a URL bar is present or not, and sometimes you need to make some slight adjustments in the elements' sizes correspondingly.

Here come s, l and d viewport modifiers to a rescue.

  • s: This is Small viewport modifier. This is the size of the viewport when the URL bar is shown.
  • l: This is Large viewport modifier. This is the size of the viewport when the URL bar is hidden.
  • d: This is Dynamic viewport modifier. This is the current size of the viewport that changes depending if the URL bar is shown or not.

You can add these modifies as prefix to an existing viewport CSS units:

.container-small {
    /* Equals to 100vh of screen height when the URL bar is shown */
    height: 100svh;
}

.container-large {
    /* Equals to 100vh of screen height when the URL bar is hidden */
    height: 100lvh;
}

.container-dynamic {
    /* Equals to 100vh of screen height regardless if URL bar is shown */
    height: 100dvh;
}
Enter fullscreen mode Exit fullscreen mode

You can combine s, l and d modifiers to get all 24 viewport CSS units:

  • vw, svw, lvw, dvw
  • vh, svh, lvh, dvh
  • vi, svi, lvi, dvi
  • vb, svb, lvb, dvb
  • vmin, svmin, lvmin, dvmin
  • vmax, svmax, lvmax, dvmax

Summary

Viewport CSS units is a great tool for developing responsive designs. They allow for fluid scaling of layout, typography, and spacing that ensures that web content looks good and functions well, no matter the screen size.

Viewport units like vw, vh, vmin and vmax are most commonly used. Consider using a clamp() function that limits the minimum and maximum size of an element on very small and very large screen sizes.

Viewport units like vi, vb and viewport modifiers s, l, d are used in some niche use cases but are a great addition to the web developer's toolkit.

This feature is highly supported by all modern web browsers:

Hope you find this blog post useful. Happy coding!

Originally published at https://antondevtips.com.

After reading the post consider the following:

  • Subscribe to receive newsletters with the latest blog posts
  • Download the source code for this post from my github (available for my sponsors on BuyMeACoffee and Patreon)

If you like my content —  consider supporting me

Unlock exclusive access to the source code from the blog posts by joining my Patreon and Buy Me A Coffee communities!

Top comments (2)

Collapse
 
rohiitbagal profile image
Rohit

Well done...nice one ....

Collapse
 
antonmartyniuk profile image
Anton Martyniuk

Thank you, sir!

On my webite (see originally published): antondevtips.com I already have few blogs about responsive design in CSS and more are coming.

Make sure to subscribe to my website to be up-to-date with useful blogs, tips and tricks.