How to access the real 100vh on iOS in CSS

2020-05-03 12:05发布

问题:

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 browser chrome is expanded. It's a well documented bug that Apple decided was actually a feature! This is a good read to explain the bug.

So what is the best way to get around this "feature"? Ideally the answer requires no JavaScript (but that seems unlikely), should be clean, not require a bunch of inline styles, and ideally can be opted into in CSS (sometimes you might want the default 100vh).

回答1:

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.



标签: ios css height