239

I just learned about a new and uncommon CSS unit. vh and vw measure the percentage of height and width of the viewport respectively.

I looked at this question from Stack Overflow, but it made the units look even more similar.

How does vw and vh unit works

The answer specifically says

vw and vh are a percentage of the window width and height, respectively: 100vw is 100% of the width, 80vw is 80%, etc.

This seems like the exact same as the % unit, which is more common.

In Developer Tools, I tried changing the values from vw/vh to % and viceversa and got the same result.

Is there a difference between the two? If not, why were these new units introduced to CSS3?

Community
  • 1
  • 1
Richard Hamilton
  • 25,478
  • 10
  • 60
  • 87

7 Answers7

264

100% can be 100% of the height of anything. For example, if I have a parent div that's 1000px tall, and a child div that is at 100% height, then that child div could theoretically be much taller than the height of the viewport, or much smaller than the height of the viewport, even though that div is set at 100% height.

If I instead make that child div set at 100vh, then it'll only fill up 100% of the height of the viewport, and not necessarily the parent div.

body,
html {
    height: 100%;
}

.parent {
    background: lightblue;
    float: left;
    height: 200px;
    padding: 10px;
    width: 50px;
}

.child {
    background: pink;
    height: 100%;
    width: 100%;
}

.viewport-height {
    background: gray;
    float: right;
    height: 100vh;
    width: 50px;
}
<div class="parent">
    <div class="child">
        100% height
        (parent is 200px)
    </div>
</div>

<div class="viewport-height">
    100vh height
</div>
jarrodwhitley
  • 826
  • 10
  • 29
Josh Beam
  • 19,292
  • 3
  • 45
  • 68
  • I had a sidebar that was nested within a bootstrap "row" and I was unable to make it full page size even after setting height: 100%. What worked for me was 100vh – S Raghav Mar 27 '17 at 05:44
  • Check this out to see a visual difference: https://stackoverflow.com/a/68306660/6908282 – Gangula Jul 08 '21 at 18:36
  • I think putting both div's inside the parent is a better example. https://jsfiddle.net/2x84tewn/1/ – mustafa candan Sep 14 '22 at 17:31
75

I know the question is very old and @Josh Beam addressed the biggest difference, but there's still another one:

Suppose you have a <div>, direct child of <body> that you want filling the whole viewport, so you use width: 100vw; height: 100vh;. It all works just the same as width: 100%; height: 100vh; until you add more content and a vertical scrollbar shows up. Since the vw account for the scrollbar as part of the viewport, width: 100vw; will be slightly bigger than width: 100%;. This little difference ends up adding a horizontal scrollbar (required for the user to see that little extra width) and by consequence, the height would also be a little different on both cases.

That must be taken into consideration when deciding which one to use, even if the parent element size is the same as the document viewport size.

Example:

Using width:100vw;:

.fullviewport {
  width: 100vw;
  height: 100vh;
  background-color: red;
}

.extracontent {
  width: 100vw;
  height: 20vh;
  background-color: blue;
}
<html>
<body>
<div class="fullviewport"></div>
<div class="extracontent"></div>
</body>
</html>

Using width:100%;:

.fullviewport {
  width: 100%;
  height: 100vh;
  background-color: red;
}

.extracontent {
  width: 100%;
  height: 20vh;
  background-color: blue;
}
<html>
<body>
<div class="fullviewport"></div>
<div class="extracontent"></div>
</body>
</html>
Dave F
  • 1,837
  • 15
  • 20
IanC
  • 1,968
  • 14
  • 23
  • 4
    The CSS `body { overflow: hidden }` will cause the scrollbars not to be displayed. – Dave F Jan 28 '19 at 16:30
  • 2
    @DaveF then you'll not be able to scroll if your page exceeds the viewport and you want vertical scrolling effect. `body { overflow-x: hidden }` should be fine – KMA Badshah Oct 19 '20 at 13:17
7

A percentage of the full viewport width. 10vw will resolve to 10% of the current viewport width, or 48px on a phone that is 480px wide. The difference between % and vw is most similar to the difference between em and rem.

A % length is relative to local context (containing element) width, while a vw length is relative to the full width of the browser window.

Yazan Najjar
  • 1,830
  • 16
  • 10
3

Thank you for your answer and code example, @IanC. It helped me a lot. A clarification: I believe you meant "scrollbar" when you wrote "sidebar."

Here are some related discussions about viewport units counting scrollbars that I also found helpful:

The W3C spec for the vw, vh, vmin, vmax units (the "viewport percentage lengths") says "any scrollbars are assumed not to exist".

Apparently Firefox subtracts scrollbar width from 100vw, as @Nolonar's comment at Difference between Width:100% and width:100vw? observes, citing "Can I Use".

Can I Use, perhaps in tension with the spec (?), says all browsers other than Firefox currently "incorrectly" consider 100vw to be the entire page width including the vertical scroll bar.

Slack Undertow
  • 781
  • 7
  • 9
1

the vw (view-width) and vh (view-height) units are relational to the view-port size, where 100vw or vh is 100% of the view-port's width/height.

For example, if a view-port is 1600px wide, and you specify something as being 2vw, that will be the equivalent of 2% of the view-port width, or 32px.

% unit is always based on the parent element width of the current element

1

There is a difference that has not necessarily been raised. 100vw includes the width of the scrool bar, while 100% does not include it. It is a small difference, but important when doing design.

  • 1
    IanC's answer does. "Since the vw account for the scrollbar as part of the viewport, width: 100vw; will be slightly bigger than width: 100%;. " – j08691 Jul 17 '19 at 20:36
1

The difference between % and vw is most similar to the difference between em and rem. A % length is relative to local context (containing element) width, while a vw length is relative to the full width of the browser window.

Hamid Shoja
  • 3,838
  • 4
  • 30
  • 45