Convert vh units to px in JS
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
zzzzBov
he/him Have something to say? Send me an email: zzzzBov at gmail dot com or find me on twitter @zzzzBov
Updated on July 20, 2022Comments
-
zzzzBov almost 2 years
Unfortunately
100vh
is not always the same as100%
browser height as can be shown in the following example.html, body { height: 100%; } body { overflow: scroll; } .vh { background-color: blue; float: left; height: 50vh; width: 100px; } .pc { background-color: green; float: left; height: 50%; width: 100px; }
<div class="vh"></div> <div class="pc"></div>
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 usingwindow.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
ormax-height
may be producing incorrect values, and there isn't an existing element with100vh
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.