Mobile issue with 100vh | height: 100% !== 100vh [3 solutions]

So there are various ways to size any element on a webpage. We are familiar with common CSS units px, em, pt (and uncommon one cm, mm, in) with support from the first version of CSS (w3.org/TR/REC-CSS1/#units).

With newer viewport units, first support came in 2013 with FF and Chrome being the first ones quickly followed by Safari and Opera. (yes, IE used to suck even in those days).

Now with newer viewport units and a ton on mobile devices, the browser communities don’t seem to agree on how to implement them in mobile devices.

In mobile, vh seems to consider the address bar as part of the viewport (IDK why is it named as ‘view’port then).

On mobile 100vh !== 100%

This creates weird issues with mobile viewport heights like this:

Mobile on 100vh is cut

Now this is an issue and indeed a very frustrating one, but we’ll discuss a couple of solutions one by one.

1. Use 100% instead of 100vh - “DOM tree nightmare”

Now the quickest, and most CSS way is to use 100% in your page for the whole DOM tree till your target element:

100% height through dom tree

This will work correctly on both mobile and desktop websites. However it is very difficult to propagate 100% through every DOM node in the branch of your element, especially if it is buried deep in the tree (however, you might not come across too many use cases like this).

2. Use JS window.innerHeight for your element - “JS hack”

The second way is to use window.innerHeight for your target element, as on mobile, it will always give you the viewable height of the viewport, but again, this again creates a problem as you will have to write this tiny JS for each of your use cases.

So can there be an easy solution, which can give you the best of both worlds?

3. Use custom vh (CSS variable) - best of both worlds

So the solution, (you might find very few solutions floating around for this typeof fix). Before proceeding with this solution, let's see what are the cons to this. This solution involves using CSS variables (custom properties) and here caniuse.com/#search=css%20var, you can see that support for CSS variables came in early 2017 for major browsers, so you might need to think if you want to use this.

Step 1

So here we’ll be creating something like this: --vh in root html

Now what we have to do is set CSS variable --vh using window.innerHeight.

window.addEventListener('resize', () => { 
  document.querySelector(':root').style
    .setProperty('--vh', window.innerHeight/100 + 'px');
})

Now you will have --vh available in your whole app.

Here comes the second step of this

Step 2

You can now use this variable anywhere in your code

height: calc(100 * var(--vh));

This works like vh (with a little too verbose representation).

  • 100vh - height: calc(100 * var(--vh));
  • 10vh - height: calc(10 * var(--vh));
  • 1vh - height: calc(1 * var(--vh));

And you can use it anywhere in your CSS code.


No Comments Yet