Mobile Chrome vh units fix

Update March 2019

Check this fix too. It works really well in most cases.


If you ever used vh units and tested your work on mobile Chrome (iOS and Android), you probably were annoyed by page jumping when you scroll.

As you probably know vh units are based on the window height. When you scroll, Chrome's address bar disappears and chrome actually changes window height. Also triggers window resize event. So when it does happen it changes the value of vh unit, making your elements resize, and page jump. On Android, keyboard toggle will do the same.

Well I made a plain JavaScript library to solve this problem.

Demo and documentation are available here.

How does it work?

On load, it will get the element and set them fixed height in pixels, using this formula:

window height / 100 * given vh value

Library listens for the window resize event, and only if both dimensions are changed (which on mobile means orientation has changed) it will recalculate and apply fixed height based on new window height. Please note that Android Chrome has a bug - when keyboard pops up, it triggers orientation change

Library will only do this if it detects Chrome on Android or iOS.

Usage

It accepts one parameter, which is an array of objects. Every object should have CSS selector and height in vh units. All elements that match given selector will be fixed.

var options = [
  {
    selector: '.Bears', // Mandatory, CSS selector
    vh: 150,  // Mandatory, height in vh units
  },
  {
    selector: '.Foxes',
    vh: 50
  },
  {
    selector: '.Horses',
    vh: 100
  }
];

var vhFix = new VHChromeFix(options);

React Component is WIP

I have a React component already done in a another project, but I need to extract it, and pack it up as a separate npm package for easier usage.

Grab the code on GitHub.

Comments (11)

Adam
30. Jan 2017, 09:35

Hi,

Can't see any mention of your vh-fix license in GitHub. Technically this means "all rights reserved". Is this accurate, or is the license just missing?

Many Thanks,

Adam

Stanko
30. Jan 2017, 09:42

Hi Adam,

It is missing, thanks for pointing it out. I just added MIT license to the repository.

Cheers!

brandon
16. Aug 2017, 05:10

Very awesome! thanks for this, you saved my project!

David
30. Aug 2017, 00:10

This is a very novel way of going about this rather annoying issue. Has there been any progress in turning this into a React component?

Stanko
30. Aug 2017, 08:38

Thanks guys!

@David, I have working React component and I plan to release it on the npm. But it depends on some other decorators and I'm thinking of the best way to separate them before publishing.

Cheers!

David
30. Aug 2017, 23:45

Makes sense. I'll keep an eye out for it.

Pierre
09. May 2018, 15:01

I just had a question about usage. I am using vh to define the size of all of my headings. Can I just use the body selector with a height of 100vh so all my responsive headings work?

Stanko
09. May 2018, 15:09

Hello Pierre,

If you want to apply it on all of your headers, just make sure they share the same class (for example .header) and pass that as an option. If you need more than one class, library supports multiple selectors as well.

var options = [
{
selector: '.header', // Mandatory, CSS selector
vh: 100, // Mandatory, height in vh units
}
];

var vhFix = new VHChromeFix(options);

Hope that helps, cheers!

Dusan
17. Aug 2018, 11:21

Nice article,

can this help with IPad devace?

Problem start after active virtual device(on browser mode), after hiding, whole content move up for 20 px and forw/back arrows are half hidden with statusbar. (Height of main wraper is 100vh)

Stanko
17. Aug 2018, 12:20

Hello Dusan, I've just tested it on iPad simulator and it works as expected.

Cheers!

Miklos
05. Jun 2019, 13:39

This is great, thanks. However, it worked for me by replacing the last line of js file with this:

element.domElement.style.height = (document.documentElement.clientHeight * element.vh / 100) 'px';