82

I have to fit an iframe in screen height. Obviously, I wanted 100% as in width but, since that doesn't work, I used 100vh. But vh like vw is not exactly 100%. In my laptop through chrome while the 100% width renders perfectly without the need for a horizontal scroll bar, vw has about a centimeter extra.

alokrajiv
  • 1,038
  • 1
  • 8
  • 7
  • 1
    FYI, as for height, `100vh` > `100%` in some mobile browsers, which once troubled me. – Rick Oct 15 '19 at 04:44

5 Answers5

150

vw and vh stand for viewport width and viewport height respectively.

The difference between using width: 100vw instead of width: 100% is that while 100% will make the element fit all the space available, the viewport width has a specific measure, in this case the width of the available screen, including the document margin.

If you set the style body { margin: 0 }, 100vw should behave the same as 100% (for an element that is a child to body).

Additional notes

Using vw as unit for everything in your website, including font sizes and heights, will make it so that the site is always displayed proportionally to the device's screen width regardless of it's resolution. This makes it super easy to ensure your website is displayed exactly the same in both workstation and mobile.

You can set font-size: 1vw (or whatever size suits your project) in your body CSS and everything specified in rem units will automatically scale according to the device screen, so it's easy to port existing projects and even frameworks (such as Bootstrap that already uses rem as unit for everything) to this concept.

Havenard
  • 27,022
  • 5
  • 36
  • 62
  • 32
    Also note thet width: 100% is relative to it's first parent with a layout. So if you have an element with width:100% inside another element that has a specific width, the child element will only take up the total width of that parent. – Reinier Kaper Nov 14 '14 at 21:59
  • 14
    I just noticed that setting an element to be `100vw` can cause a horizontal scrollbar to appear when a vertical scrollbar is visible. According to [Can I use](http://caniuse.com/#feat=viewport-units), only Firefox exhibits correct behavior by subtracting the scrollbar width from `100vw`. For every other browser, you will need to use `100%` instead. – Nolonar Oct 11 '16 at 10:02
  • 2
    This is (now?) incorrect. The [current editor draft docs state](https://drafts.csswg.org/css-values-3/#viewport-relative-lengths) that viewport lengths must ignore scrollbars and [MDN additionally documents](https://developer.mozilla.org/en-US/docs/Web/CSS/length#Viewport-percentage_lengths) that this is only with overflow: auto; if overflow is set to scroll (with scrollbars always visible) then viewport lengths do respect them (didn't see it in the draft myself). 100% references the parent element not the viewport, and as such does not ignore scrollbars in any case. – Kissaki Jun 02 '18 at 14:09
  • 2
    As far as I can see the differentiation on margins is incorrect. When I set a child to 100% width or 100vw width and add and remove a margin from the body they behave the same way. – Kissaki Jun 02 '18 at 14:15
  • 2
    "100vw should behave the same as 100%.", not if there is a scroll bar to the right. – Metatron5 Feb 07 '19 at 15:21
59

Havenard's answer doesn't seem to be strictly true. I've found that vw fills the viewport width, but doesn't account for the scrollbars. So, if your content is taller than the viewport (so that your site has a vertical scrollbar), then using vw results in a small horizontal scrollbar. I had to switch out width: 100vw for width: 100% to get rid of the horizontal scrollbar.

WasiF
  • 26,101
  • 16
  • 120
  • 128
James Filby
  • 591
  • 5
  • 2
  • 3
    https://stackoverflow.com/questions/23367345/100vw-causing-horizontal-overflow-but-only-if-more-than-one – Eli Jul 05 '17 at 22:23
7

You can solve this issue be adding max-width:

#element {
   width: 100vw;
   height: 100vw;
   max-width: 100%;
}

When you using CSS to make the wrapper full width using the code width: 100vw; then you will notice a horizontal scroll in the page, and that happened because the padding and margin of html and body tags added to the wrapper size, so the solution is to add max-width: 100%

corn on the cob
  • 2,093
  • 3
  • 18
  • 29
Tahseen Alaa
  • 342
  • 4
  • 9
  • Can you describe said issue please? – corn on the cob Sep 29 '20 at 17:37
  • When you using CSS to make the wrapper full width using the code ``` width: 100vw;``` then you will notice a horizontal scroll in the page, and that happened because padding and margin of ```html``` and ```body``` tags added to the wrapper size, so the solution to add ```max-width: 100%``` – Tahseen Alaa Sep 30 '20 at 16:12
2

@Havenard's answer provides the perfect explanation for the question. Adding to that, this provides a visual representation of the difference.

You'll be able to notice the key difference between 100vw and 100% when you have a site with scrollbars and an element that is supposed to fit the entire width of the screen.

Option 1

Below is an example of the same.
All i'm doing in the code below is changing the width of <h1> tag from 100vw to 100% when you hover over it.

body {
  /* margin: 0; */
}

.scroll {
  height: calc(110vh);
}

h1 {
  width: 100vw;
  /* width: 100%;*/
  text-align: right;
  outline: 5px solid black
}

h1:hover {
  width: 100%;
}

h1:before {
float: left;
  content: "100vw "
}

h1:hover:before {
  content: "100% "
}
<div class="scroll">
  <p>Hover over the below block</p>
  <h1>Width</h1>
</div>

If you run the above code snippet and hover the text, you'll notice 2 things:

  1. the horizontal scrollar disappears
  2. the entire text will be visible to you

Note: after running the above snippet, you can play around with above code in browser devtools to see how it affects the elements


Option 2 (Chrome and Edge)

.scroll{
height: calc(110vh);
display: flex;
align-items: baseline;
}

h1{
width: 100vw;
/* width: 100%; */
text-align:right;
outline: 10px solid black
}
<div class="scroll">
    <h1>Test</h1>
  </div>

Another way to visually see the difference in your own project is by setting a display:flex style to an element with 100vw.

When you highlight this elements in browser devtools, You can notice the a leftward point arrow at the right end of the element. Also you can see than the shading of the highlighted elements spans across the scroll-bar, indicating that it is considering the entire screen-width (including scroll-bar width)

100vw vs 100% visual difference


Other questions, that address similar issue are:

  1. 100vw causing horizontal overflow, but only if more than one?
  2. CSS Units - What is the difference between vh/vw and %?
  3. Prevent 100vw from creating horizontal scroll
Gangula
  • 5,193
  • 4
  • 30
  • 59
0

body {
  /* margin: 0; */
}

.scroll {
  height: calc(110vh);
}

h1 {
  width: 100vw;
  /* width: 100%;*/
  text-align: right;
  outline: 5px solid black
}

h1:hover {
  width: 100%;
}

h1:before {
float: left;
  content: "100vw "
}

h1:hover:before {
  content: "100% "
}
<div class="scroll">
  <p>Hover over the below block</p>
  <h1>Width</h1>
</div>