frontend
Viewport Units, the CSS You Didn't Know About But Should
Because CSS done right is awesome
Introduction
CSS can be both the greatest thing in the world and the most frustrating thing in the world for a web developer at exactly the same time.
It is a joy when it works the way we envision it — it’s beautiful, it makes the site intuitive, accessible, possibly animated — just good in all the ways. But the effort, time and the pain of getting everything pixel perfect can be totally maddening to the point where we want to tear our hair out and the meme above is very, very real to us.
To be honest, I fall more towards the side of “I like CSS, and all that it does for me, even when it takes forever to get it there,” whereas some of my coworkers have less positive feelings about it. I don’t normally get to dive deep into things like animations, multi-browser support or some of the really bleeding-edge CSS stuff because the software I work on day-in and day-out is an internal application to help other employees at my company do their jobs better.
But I still really enjoy (usually) when I pick up a front end feature that gives me the opportunity to dust off my CSS skills and implement some transitions or hover states, or learn some new cool CSS tricks I’ve not used before.
Today, I want to share something I’ve been learning more about lately: CSS viewport units. They’re awesome for so many reasons.
CSS Viewport units
Viewport units have been around in CSS for a few years now, but I don’t see them used all that often, and I think part of it is because people just aren’t that aware that they exist. And there’s so much to learn and do in CSS, I’m not terribly surprised that’s the case. I’m sure there’s a ton of CSS tricks I’m not aware of either.
In case you haven’t heard of viewport units, let me give you a quick overview of what they are.
They are truly responsive length units in the sense that their value changes every time the browser resizes. — CSS Viewport Units: A Quick Start
If that doesn’t immediately make sense or sound incredibly useful to you right off the bat, bear with me, there’s some cool examples coming up.
But first, let’s define viewport units in terms of their CSS.
Viewport Height (vh)
This unit is based on the height of the viewport. A value of 20vh
is equal to 20%
of the viewport height.
Viewport Width (vw)
This unit is based on the width of the viewport. A value of 10vw
is equal to 10%
of the viewport width. If a browser window is 1200px wide, the viewport width will be 120px. Likewise, if a mobile view browser is 480px wide, the viewport width would be 48px.
These next two are a bit more interesting than the standard vh
and vw
, but also not as commonly used either.
Viewport Minimum (vmin)
The viewport minimum is calculated as a percentage of the viewport width or height, whichever is smaller at the time. 20vmin
will resolve to 20%
of the current viewport width in portrait orientations, and 20%of the viewport height on landscape orientations.
Viewport Maximum (vmax)
For viewport maximum (like viewport minimum), it is based on a percentage of the viewport width or height, whichever is larger at the time. 15vmax
will resolve to 15%
of the current viewport height in portrait orientations, and 15%
of the viewport width on landscape orientations.
Personally, I don’t find the last two as useful as the first, but that’s just me.
Now, after making sure we’re all on the same page, let’s get to the interesting parts — the examples.
Benefits of using viewport units
At this point, you might be thinking to yourself, ok, that’s cool, but how does this differ or improve upon the percentages and media queries I use in my CSS today?
I’m so glad you asked...
Example 1: Child components can be larger than their parent components
If you look at the CodePen example above, you’ll see that traditionally, if a child div is using percentages to calculate its size, it bases those percentages off of its parent component.
Using viewport units, however, makes it possible to make child components larger than the parent component — they base their size off of the size of the viewport instead of their parent component.
Helpful? In certain situations, you betcha.
Example 2: Background images can be responsive without media queries
The example here shows the power of both viewport height and viewport width. If you look at the images and colors set as backgrounds, you’ll notice that when the browser resizes, the images (and text centered in them), resize right along with them because it’s using vh
and vw
to set the height, width and padding.
.fullscreen {
width: 100vw; /* this will stretch the width of the viewport */
height: 100vh; /* this will stretch the height of the viewport */
color: white;
padding: 40vmin 1rem;
}
No muss, no fuss, just perfectly centered, resizing backgrounds. Tell me that’s not awesome.
Example 3: Font Sizes can Scale with the Help of calc()
Another really cool thing that can be done with vw
and vh
is with calc()
. By using calc()
, font-sizes and headers can responsively resize based purely on the viewport.
In the example above, you’ll notice the h1
and the p
text font-sizes
automatically resize and grow accordingly with the help of calc()
.
h1 {
padding: 10vmin 1rem;
font-size: calc(32px + 1.5vw);
background-color: #BF6FE5;
}
p {
font-size: calc(16px + 0.5vw);
margin: 0 0 10vmin 0;
}
And the padding for the h1
tag also uses the vmin
tag in addition to the 1rem
static padding, so regardless of whether the height or width of the browser is greater, it will always have some padding keeping it from running up against the edges of the viewport.
I know these may seem like little things, but just imagine the CSS developers are saved from writing based on improvements like this.
If you like these kinds of examples, I’d highly recommend the CSS articles at the bottom of this post to see more of the possibilities that can be achieved with CSS viewport units.
Conclusion
CSS gives websites the ability to be unique, beautiful, useful and delightful, and it can sometimes make the engineers who use it want to quit their jobs.
Ultimately though, it feels so rewarding to me when I get it right and users tell me how much better an application makes their jobs. CSS viewport units, though often overlooked in favor of flashier frameworks like flexbox and grid, have some super useful applications that can reduce the amount of code needed to make a site responsive and child elements independent of their parents in some ways
It definitely has a place in my CSS arsenal, now that I have a better understanding of its usefulness.
Check back in a few weeks, I’ll be writing about JavaScript, ES6 or something else related to web development.
Thanks for reading, I hope you can find some ways to incorporate CSS viewport units into your own sites, and (hopefully) reduce the amount of CSS needed along the way.
References & Further Resources
Want to be notified first when I publish new content? Subscribe to my newsletter.