loading...
Can we fix it? Yes we can!

Published: July 2020

How to fix the viewport height issue on mobile browsers

In some mobile browsers the Viewport height is taller than the visible part of the page. Is there a fix and how can I adapt it in Tailwind CSS and Vue JS? Here is the answer to your question!

Markus A. Wolf

Author: Markus A. Wolf
Taipei / Taiwan – UX Designer and product owner - worked in Germany, California / Silicon Valley and now Taiwan for international clients.

At first: It is not a bug it is a feature

And unfortunately the way mobile browsers handle the viewport height this is really intentional. The base problem is that if the user scrolls down the visible area changes dynamically.

If the browser would update the CSS viewport height appropriately it should be done while scrolling. The result will be changing layouts all the time, super messy, or like Benjamin wrote as a comment “it would look like shit”.

So how can you solve it?

In Tailwind CSS you can use the utility “.h-screen” or “.min-h-screen” to set the height or min-height of an element. Tailwind uses logically the value “100vh” to make this possible and here comes the approach.

The Solution with Tailwind CSS - works in every other CSS framework too…

…is to overwrite the “x-screen” definitions in Tailwind CSS with the dynamic value of a CSS custom property also known as CSS variable.

Overwrite the utility with “var(—vh)” and define the custom property dynamically with javascript on-load and on-resize. I use this approach in all my Vue js applications and websites - it works perfectly.

export default {
  // ...
  methods: {
    setViewHeight: function() {
      let vh = window.innerHeight * 0.01
      document.documentElement.style.setProperty('--vh', `${vh}px`)
    },
  },
  mounted: function() {
    this.setViewHeight()
    window.addEventListener('resize', () => {
      this.setViewHeight()
    })
  },
  // ...
}

Redefine the utility classes in Tailwind CSS

Redefining the CSS class in the tailwind.css file is not the best solution because Tailwind CSS doesn’t know the new values.

So if you would use “h-screen” with Tailwinds directives you would get the old - and wrong - value. The best way is to redefine the height and min height utility or use a plugin function to redefine the utilities you want.

module.exports = {
  // ...
  theme: {
    // ...
    height: theme => ({
      auto: 'auto',
      ...theme('spacing'),
      full: '100%',
      screen: 'calc(var(--vh) * 100)',
    }),
    minHeight: theme => ({
      '0': '0',
      ...theme('spacing'),
      full: '100%',
      screen: 'calc(var(--vh) * 100)',
    }),
    // ...
  },
  // ...
}

You can find the code example in my collection of best practices in Vue js and Tailwind CSS at Github: App.vue and tailwind.config.js.

This fix with CSS custom properties is not the only way of handling this situation - an alternative way is to use “-webkit-fill-available”. If you are interested in this way you can find it here.

Latest Tailwind CSS articles

Pacifer

Published: July 2020

Is Tailwind CSS a framework only for dummies?

Is it true that you don’t need CSS skills if you only use utility classes? No it’s not! To get the most out of Tailwind CSS and other utility class frameworks you have to have advanced CSS skills. Otherwise you end up with too large HTML files and can’t use the magic of Purge CSS.

Vue JS logo with many connections to other places

Updated: June 2020

Tutorial for a flexible Basic Icon Vue js Component

An easy to use Vue js Base Icon Component you can use everywhere in your single or multi page application. Have control over all icons you are using inside your app.