This background section is large; here's a handy link to the new unit section if you would like to skip ahead.
However, I think it can be useful to understand how we got where we are. Additionally, this information will be useful to understand when talking about the
dvw units later.
Note: while I'll focus mainly on the
vh unit, please know that the
vw unit had the same issues. It's just easier to talk about one of them.
vh unit, as it originally existed, was defined as
Equal to 1% of the height of the initial containing block.
The initial containing block (ICB) definition can be found here, but I think the first bullet point summarizes it well (emphasis mine): The containing block in which the root element lives is a rectangle called the initial containing block. For continuous media, it has the dimensions of the viewport and is anchored at the canvas origin; In other words, it's the same size as the viewport; or the same size as the content of your website that you can see without scrolling.
Expand for more info about the initial containing block
The initial containing block (ICB) definition can be found here, but I think the first bullet point summarizes it well (emphasis mine):
The containing block in which the root element lives is a rectangle called the initial containing block. For continuous media, it has the dimensions of the viewport and is anchored at the canvas origin;
In other words, it's the same size as the viewport; or the same size as the content of your website that you can see without scrolling.
Which is very useful and good... that is, until mobile browsers started doing some tricks to maximize your phone's screen space. To see these tricks, open any webpage on your phone and scroll around some bit, while paying attention not to the content of the webpage but the browser's UI itself.
You may have noticed that the browser's UI changes size as you scroll. And if the browser's UI and viewport changes size, then the question regarding
vhis 1% of the initial containing block (ICB), but the ICB changes sizes as a user scrolls, what does
The first and simplest answer to that question was "
vh changes as the ICB changes." Logically, it would seem like that should be the final answer, too.
However, there's a problem with this solution:
Let's say you have a phone that has
100px of screen space. When you load up a page, the browser UI takes up
15px which leaves
85px left for your website's content.
However, your browser is Super Cool, so when you scroll down the browser UI only takes up
10px, which leaves your website content with
90px. Or, in table form:
|Browser UI State||Browser UI||
|See everything / maximized / first page load / on scroll upward||
|Small / minimized / on scroll downward||
On your Fancy Website™, you have 5
<section style="height: 100vh"> elements on your page. When someone first loads the page, each
85px tall. But as they begin to scroll down, the browser UI begins to change size which causes those section elements to grow by 5 pixels, to a total of
Now, let's say the user's now at the bottom of the page looking at the 5th section element. They decide they want to scroll up, which has the side effect of changing the browser UI to the maximum size. That causes
vh to shrink, and your sections are now all
5px smaller; when you're at the bottom of the page, that's a total of
20px of difference (4 sections with
Just by scrolling upwards a tiny bit, the content of your page has jumped upwards 1/5 of your total screen space (100px total / 20px smaller)! That is a very jarring experience, and honestly it sucked.
Imagine if you had used
vh for things like
font-size, and how that would look!
With this problem in mind, in 2015 Safari / Webkit engineers decided to change the behavior of
Dynamically updating the height was not working, we had a few choices: drop viewport units on iOS, match the document size like before iOS 8, use the small view size, use the large view size.
From the data we had, using the larger view size was the best compromise.
In other words, a dynamic
vh unit was not great, so they changed it to be a static unit equal to the size of the viewport when the browser UI was its smallest (and the content / "view size" was the largest).
About a year later Chrome / Blink engineers agreed and also updated
vh units to do the same.
Which is where we are now (as of the time of this writing) with
One of the problems with
vh being the "largest view size" is that anything that is
height: 100vh is now larger or overflows the screen when you first load a page. It's pretty difficult, using just CSS, to get content to fit the page exactly.
lvw units are defined as:
The large viewport-percentage units (lv*) are defined with respect to the large viewport size: the viewport sized assuming any UA interfaces that are dynamically expanded and retracted to be retracted.
In other words, the size when the browser UI is the smallest and the website content is the largest.
lvh is essentially how the
vh unit currently (at the time of this writing) acts.
svw units are defined as:
The small viewport-percentage units (sv*) are defined with respect to the small viewport size: the viewport sized assuming any UA interfaces that are dynamically expanded and retracted to be expanded.
svh gives you units that you can use to fill the screen when the browser UI is at its largest, and the website content is at its smallest.
dvw units are defined as (with emphasis mine):
The dynamic viewport-percentage units (dv*) are defined with respect to the dynamic viewport size: the viewport sized with dynamic consideration of any UA interfaces that are dynamically expanded and retracted. This allows authors to size content such that it can exactly fit within the viewport whether or not such interfaces are present.
The sizes of the dynamic viewport-percentage units are not stable even while the viewport itself is unchanged. Using these units can cause content to resize e.g. while the user scrolls the page. Depending on usage, this can be disturbing to the user and/or costly in terms of performance.
dvw units may sound good on paper, the caveats noted in the definition above (and in the first problem & solution section above) actually lead me to believe that you should only use them in very rare and specific situations.
With these new units, where does
vw sit? Interestingly enough, they are currently defined as:
The UA-default viewport-percentage units (v*) are defined with respect to a UA-defined UA-default viewport size, which for any given document should be equivalent to the large viewport size, small viewport size, or some intermediary size.
Personally, I find this definition to be too vague, and I have concerns about how this will affect users and developers. I guess we'll see where it goes!