CSS vh (dvh, lvh, svh) and vw units. What's the difference
Background
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 dvh and 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.
History of vh
The vh unit, as it originally existed, was defined as
Equal to 1% of the height of the initial containing block.
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 vh became:
If vh is 1% of the initial containing block (ICB), but the ICB changes sizes as a user scrolls, what does vh really equal?
First Solution, First Problem
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 cool, so when you scroll down the browser UI only takes up 10px, which leaves your website content with 90px.
On your site, you have 5 <section style="height: 100vh"> elements on your page. When someone first loads the page, each <section> is 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 90px!
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 5px each).
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!
Second Solution, Second Problem
With this problem in mind, in 2015 Safari / Webkit engineers decided to change the behavior of vh units:
领英推荐
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.
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 vh.
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.
And so, in 2019, a new CSS proposal was born . And in 2021, that proposal, with feedback and improvements, was accepted in the CSS spec as several new units!
The New CSS Units
Large Viewport Units
The lvh & 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.
Small Viewport Units
The svh & 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.
Essentially, 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.
Dynamic Viewport Units
The dvh & 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.
While the dvh & 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.
Traditional Viewport Units
With these new units, where does vh and 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.
Senior Frontend Developer
1 个月Welcome your comments