This is a self Q&A
If you\'ve ever tried to use 100vh
in CSS on iOS you will have found that it isn\'t actually 100vh when the brow
Set a root CSS var like so in your stylesheet:
// CSS vars
:root {
--real100vh: 100vh;
}
Then in JavaScript, on load (or jQuery ready) and on resize, you want to run this code:
set100vhVar() {
// If less than most tablets, set CSS var to window height.
let value = "100vh"
if (this.winWidth <= 1024) {
value = `${window.innerHeight}px`
}
document.documentElement.style.setProperty("--real100vh", value)
}
Now you can simply use the CSS: height: var(--real100vh);
wherever you want 100vh
to actually be the real 100vh
on mobile, and this will simply work!
It looks better if you also add a transition: height 0.4s ease-in-out;
on the same element, so it doesn't snap when you scroll down on mobile.
The advantage of using a CSS var to do this is that you can override this whenever you like, for example you might want certain breakpoints to be height: 500px
, and this is hard to do if you use an inline style. You can also use this inside calc()
, like height: calc(var(real100vh) - 100px);
which is useful for fixed headers.
If you use Vue/Nuxt, take a look at how we have implemented that here.
CSS Grid is the solution.
.grid-container {
height: 100vh;
grid-template-columns: 1fr;
grid-template-rows: 30px 1fr 30px
}