Notes
Issues with making mobile screens take full height `100vh`
why 100vh is taller than the visible screen on mobile browsers, and the workaround of setting a –vh css variable from window.innerHeight
CSS & Sass
2 minutes
100vhdoes not take into account the browser bar or the navigation menu.- On iOS Safari and Google Chrome, the viewport will not resize in response to the URL being shown or hidden. This is a compromise by design, to avoid page jarring, reflows and relayout.
The workaround
Calculate the window’s innerHeight, and use that as a CSS variable instead of vh
1let vh = window.innerHeight * 0.01;
2document.documentElement.style.setProperty('--vh', `${vh}px`);
1.element {
2 height: 100vh; /* Fallback */
3 height: calc(var(--vh, 1vh) * 100);
4}
var(--vh, 1vh)will evaluate tovar(6.67px, 1vh)on an iPhone 6/7/8 (667px high).- the first argument is the custom property name
--vhin this case, and the second argument is the desclaration value1vhwhich serves as the fallback if the first argument is invalid. So, use calculated--vh, and if it’s not available, use1vh.
var( <custom-property-name> [, <declaration-value> ]? )
In the wild
Here is how you’d do a 100vh above the fold layout with a header, hero area and footer..
1.layout-above-the-fold {
2 height: 100vh;
3 height: calc(var(--vh, 1vh) * 100);
4}
5
6.logo { height: calc(var(--vh, 1vh) * 20); }
7.hero { height: calc(var(--vh, 1vh) * 65); }
8.footer { height: calc(var(--vh, 1vh) * 15); }
Although, instead of using fixed heights for elements, using something like Flexbox or CSS grid is a better option.