Difference between Width:100% and width:100vw? - html

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.

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'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.

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%

#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{
content: "100vw "
}
h1:hover:before{
content: "100% "
}
<div class = "scroll">
<h1>Width</h1>
</div>
If you run the above code snippet and hover the text, you'll notice 2 things:
the horizontal scrollar disappears
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)
Other questions, that address similar issue are:
100vw causing horizontal overflow, but only if more than one?
CSS Units - What is the difference between vh/vw and %?
Prevent 100vw from creating horizontal scroll

Related

Resize HTML video to fit into parent container height *and* width

I've read a lot of SO posts on resizing video to fit the browser and/or parent element, but none of them do what I need. I have a single-page app with overflow: hidden so the app doesn't scroll.
The app has various display:flex containers, and in one of those I want to have a 16x9 video.
I want the whole video to always fit into its container (so there will be bars on top/bottom if the container is too wide, and bars on left/right if the container is too tall). I can use width: 100% on the video to make it resize based on container width, but I can't figure out any way to make it shrink to fit when the container height gets smaller. (I'm guessing that's because most web pages grow vertically, so restricting based on height is less important.)
I've figured out that, at least on Chrome, the video tag does not allow height to be a percentage, and the W3C spec agrees with that, unfortunately. I've tried the trick with a relative-positioned video-wrapper with padding-bottom: 56.25% and then putting the absolute-positioned video into that, but it still cuts off the bottom of the video when the container is too wide.
Here's a jsfiddle; it's easier to see there than to write about it: https://jsfiddle.net/darkstarsys/q1fr9jwd/2/
In there you'll see the video reacts correctly to its container's width, but the bottom of the video is cut off when the height is small. Play with the main element's height and width to see how it reacts to its container size.
I'd like to avoid a Javascript-based solution if possible; seems like CSS ought to be able to do this somehow.
I'm not sure if this is what you want, but try it:
.main {
/*overflow: hidden;*/
/* TRY ASPECT RATIOS HERE
800w x 300h doesn't work -- bottom gets cut off */
width: 800px;
height: 300px;
background: red;
}
.video-wrapper {
display: flex;
height: 100%;
}
.video {
width: 100%;
height: auto; /* spec says no percent allowed here */
}

Why does translateZ with overflow hidden cause a slight movement to the right?

I was trying to create a parallax effect using pure CSS based on Google's Performant Parallaxing. This involves using perspective, translateZ, and scale. It also involves using a lot of "layers" of PNG images stacked on top of one another. However, there was a problem on those layers.
In this example, only one layer of the PNG image is shown because it is sufficient to show the problem. Here is an image of the problem (a white space on the left side of the div).
The problem arises in the following situation: the vertical scrollbar of body is visible, the horizontal scrollbar of body is hidden due to overflow, and the parallax-ed image is set to a width of 100%. Strangely, this problem can be solved simply by setting the width of the image to 100vw instead of 100%. Here's the code showing the problem.
html, body {
margin: 0;
width: 100%;
height: 100vh;
overflow-x: hidden;
}
body {
perspective: 100px;
}
.background {
width: 100%;
height: 101vh;
background: url('https://i.pinimg.com/originals/13/17/ba/1317ba3fb0901d7b6be59f9c21d39d12.jpg');
transform: translateZ(-300px) scale(4);
}
<div class="background"></div>
Why does the white space gap appear on the image when its width is 100% and not 100vw?
100% is respecting the width of the inner window minus the scrollbar (1903px computed width for me) whereas 100vw is respecting the width of the entire viewport with no regard for the scrollbar (1920px computed width for me).
The reason 100vw 'works' here is because the image is 17px bigger than its counterpart. It also works with 100% width and anything below 100vh height since the scrollbar goes away and 100% is equal to 100vh.
When you add in the translateZ with a negative value the element you're translating gets visually smaller so the gap you're seeing is a product of that. If you want the image to fill the screen, use a smaller value in your transform or a higher value in scale or width.

Trying to get my image to fill the viewport using overflow: hidden

I have a 5000x3700 image that I'm using the overflow:hidden property on to get it to fill the viewport and not cause any scroll bars.
<!DOCTYPE html>
<head>
<title> Animations </title>
<style>
*{
margin: 0;
padding: 0;
}
.jumbotron1{
position: relative;
overflow: hidden;
}
</style>
</head>
<body>
<img src="books.jpeg" class="jumbotron1">
</body>
</html>
The above code doesn't do anything for me however. It just displays the full sized image with scroll bars. My problem is fixed if I remove the overflow property and just add width and height for the * element.
*{
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
My question is, why is overflow not working and why is the above addition of height and width working?
Why is overflow not working?
The above code doesn't do anything for me however. It just displays the full sized image with scroll bars . . . my question is, why is overflow not working
TL;DR Version: overflow:hidden is not causing the scrollbars, your image is full size and can't fit in the browser window, so the browser is adding the scrollbars.
Actually, overflow is working exactly as expected. First, and this is really important to understand, setting overflow:hidden will cause content to be hidden when it is larger than the element's block formatting context. Basically, if an element is within a box of a certain size, overflow:hidden will cause anything larger than the box to be clipped (or hidden from view)
Your initial code simply places the image on the page at full size. You have nothing constraining its size...
.jumbotron1 {
position: relative;
overflow: hidden;
margin: 0;
padding: 0;
}
Its parent elements (body and html) are also not constrained in size. The 'box' that your image is in is equal to its original size so there is nothing 'larger' than the box to be clipped - so you might expect no scrollbars. Indeed, overflow:hidden is actually not causing the scrollbars.
Really, your image is being clipped by the viewport (meaning the browser window) and that's why you are seeing scrollbars. Setting overflow:hidden will not resize the image to size of the viewport. If you had a gigantic monitor and your viewport was 5000px wide, then you would not see scrollbars.
Why is the addition of height and width working?
TL;DR Version: You've set every element to be the same dimensions as the viewport, so your image and browser window are now the same size - no scrollbars needed.
Your additional code sets the height and width of every element to full height and width of the root element (the html element). Since you have set no dimensions for the html element, it takes on the height and width of the viewport.
* {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
In effect, you are setting the dimensions of your image to the same dimensions of the viewport. Since the image and the browser window are the same size, of course there will be no scrollbars.
I would not recommend using this as a fix to your problem. Using * will apply your style to every element in the document. That means all block level elements will also have height:100% and width:100%, so even a <p> element would literally cover your entire screen.
Plus, your image will not be proportionate. The height and width will both be based off of the browser window size, and you will end up with crazy image proportions like you can see here: https://codepen.io/noahjwhitmore/pen/rpZwyM
Your Solution - vh Units
Setting an image height using vh units is going to solve your problem. Each vh unit represents 1% of the height of the viewport. So, applying `height:100vh' to your image should do the trick. If you put the image in the background of an element, you can even keep it centered.
.jumbotron1 {
background-image: url('books.jpeg');
background-position: center;
background-size: cover;
background-repeat: no-repeat;
height: 100vh;
/* You may wish to un-comment the next
property if you want the image to be
the exact dimensions of the viewport */
/* width: 100vw */
}
Hi will it be okay if you set the image as a background image?
If yes just add a background to body and set the height to 100 percent of your viewport.
body {
background-image("books.jpeg");
background-repeat: no-repeat;
background-size: cover;
background-position: center;
height: 100vh;
}

css fill height of screen when window is zoomed 100%

How do you fill the height when the website is zoomed 100%? When zoomed out i don't want the element to keep filling the screen. To be more clear, when a user enters the website and the website is zoomed by the default 100% the whole screen should be filled with a color. But when the user scrolls down or zooms the fill should not dynamically change its height.
From comments i edit the code to get a better result, but now there is gaps around the element:
header.mainHeader {
background-color: #282828;
width: 100%;
height: 100vh;
box-sizing: border-box;
}
First, you're setting the position: fixed of the .mainHeader class. This causes the element to always be at the same position in the viewport, regardless of zoom-level or scrolling position.
Remove this position: fixed, and its corresponding top and left properties.
You're currently setting the height to 100% of its parent element, so it would always be as big as that.
To set the height using the viewport's (visible page area) height, you can use vh units, equivalent to percentage of the viewport height (vh) - likewise for width and vw.
So, to set the height of the element to 100% of the viewport height, you can simply do:
height: 100vh;
EDIT - NOTE: the vh unit isn't supported by all browsers (I've found some, trust me). So I would recommend setting a fallback value, above the vh one, to prevent incompatibility. For example:
height: 500px; // fallback value if browser doesn't support vh
height: 100vh; // this value overrides the above one, if the browser supports vh
You might then need to remove padding and/or margin from the body or other elements, if you're seeing whitespace around the element. Have a play about to get the right effect.
For example:
body {
padding: 0;
margin: 0;
... other properties
}
Please find a JSFiddle of this in action: https://jsfiddle.net/s49p6Laj/
Sample code:
HTML
<div class="header">
I fill the viewport!
</div>
<div class="other-stuff">
// All your other content here...
</div>
CSS
// Set the body's margin and padding to 0
body {
margin: 0;
padding: 0;
}
// Make the container fill the viewport
.header{
width: 100%;
height: 100vh;

Setting a dynamic height for divs in mobile devices

Check this FIDDLE
This is like a mobile phone prototype where I have fixed height of 50px for header-div and footer-div.
I want the content-div to dynamically adjust its height according to the main-container (which here is acting as mobile screen size). Adjust in such a way that the content overflow should be scrollable in the visible content-div height only.
If I put header-div and footer-div height both 10% and content-div height 80%. So that it arranges according to the screen size. Trouble here is that the header and footer heights will vary according to screen sizes and as a result will make header-div and footer-div bigger/smaller in height.
This is why I have set a certain height for header-div and footer-div both that is 50px. Now I want the content-div to be adjusted in such a way that it dynamically changes its height in accordance to the main-container (parent div)
Appreciate any help. Thanks.
I tried this and I am not sure if you would like it that way but here's what I've got for you...
Change your CSS code for main-container to this.
.main-container {
width: 420px;
height: auto;
background-color: #f7f7f7;
}
change your css code for main-container
.main-container {
width: 420px;
height: 1.2em; //change as per your requirements
background-color: #f7f7f7;
}
Web Style Sheets
CSS tips & tricks