Convert vh units to px in JS

zzzzBov picture zzzzBov · Dec 8, 2015 · Viewed 13.9k times · Source

Unfortunately 100vh is not always the same as 100% browser height as can be shown in the following example.

The issue is more pronounced on iPhone 6+ with how the upper location bar and lower navigation bar expand and contract on scroll, but are not included in the calculation for 100vh.

The actual value of 100% height can be acquired by using window.innerHeight in JS.

Is there a convenient way to calculate the current conversion of 100vh to pixels in JS?

I'm trying to avoid needing to generate dummy elements with inline styles just to calculate 100vh.

For purposes of this question, assume a hostile environment where max-width or max-height may be producing incorrect values, and there isn't an existing element with 100vh anywhere on the page. Basically, assume that anything that can go wrong has with the exception of native browser functions, which are guaranteed to be clean.

The best I've come up with so far is:

function vh() {
    var div,
        h;
    div = document.createElement('div');
    div.style.height = '100vh';
    div.style.maxHeight = 'none';
    div.style.boxSizing = 'content-box';
    document.body.appendChild(div);
    h = div.clientHeight;
    document.body.removeChild(div);
    return h;
}

but it seems far too verbose for calculating the current value for 100vh, and I'm not sure if there are other issues with it.

Answer

fixmycode picture fixmycode · Dec 8, 2015

How about:

function viewportToPixels(value) {
  var parts = value.match(/([0-9\.]+)(vh|vw)/)
  var q = Number(parts[1])
  var side = window[['innerHeight', 'innerWidth'][['vh', 'vw'].indexOf(parts[2])]]
  return side * (q/100)
}

Usage:

viewportToPixels('100vh') // window.innerHeight
viewportToPixels('50vw') // window.innerWidth / 2