100vh
does not take into account the browser bar or the navigation menu.
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 to var(6.67px, 1vh)
on an iPhone 6/7/8 (667px high).--vh
in this case, and the second argument is the desclaration value 1vh
which serves as the fallback if the first argument is invalid. So, use calculated --vh
, and if it’s not available, use 1vh
.var( <custom-property-name> [, <declaration-value> ]? )
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.