get reliable CSS vh
sizes for 1kb gzipped
- the problem
- why not use viewport-units-buggyfill?
- use
- example
- configuration
- about browser support
- demo
- caveats
- other stuff
Browsers don't always compute the vh unit the same way.
Some mobile browsers compute the vh
CSS unit without taking care of the url bar.
That means that a 100vh
div will overflow the viewport by the size of the url bar.
This is the current behavior for:
As explained in the chrome post, that make sense but make it hard to have a full hero top block.
This script will measure the difference and put it in a CSS var. You can read more on this css-trick article by Louis Hoebregts
It's doing a very good job:
https://github.com/rodneyrehm/viewport-units-buggyfill
But it has some problems with media-queries:
rodneyrehm/viewport-units-buggyfill#13
<script src="https://unpkg.com/vh-check/dist/vh-check.min.js"></script>
<script>
(function () {
// initialize the test
var test = vhCheck();
}());
</script>
npm install vh-check
var check = require('vh-check')
var test = vhCheck() // return an object (see below)
npm install vh-check
import vhCheck from 'vh-check'
const test = vhCheck()
- It will update the
vh-check
CSS custom property if needed vh-check
will be updated onorientationchange
eventvh-check
will not be updated on scroll event by default
vh-check will return a full object:
{
isNeeded: false,
// wether or not it's needed
value: 0,
// the CSS var value
vh: 480,
// a 100vh div size
windowHeight: 480,
// same value as window.innerHeight
offset: 0,
// difference between the above sizes
recompute: function computeDifference(),
// call this to programmatically get all the values and set the CSS var
// - this can be useful if you want to add your own listeners
// that will trigger a computation
unbind: function unbindVhCheckListeners(),
// call this to remove any window listeners created by vh-check
},
vhCheck()
main {
height: 100vh;
/* If you need to support browser without CSS var support (<= IE11) */
height: calc(100vh - var(--vh-offset, 0px));
/* enable vh fix */
}
You can pass the CSS var name as a param to vhCheck()
(default vh-offset
)
vhCheck('browser-address-bar')
In your CSS you will have to reference:
main {
min-height: 100vh;
min-height: calc(100vh - var(--browser-address-bar, 0px));
}
vh-check
allows you to have more control by passing a configuration object.
vhCheck({
cssVarName: 'vh-offset',
force: false,
bind: true,
redefineVh: false,
updateOnTouch: false,
onUpdate: function noop() {},
})
type: string
default: 'vh-offset'
Change the CSS var name
type: boolean
default: false
Set the CSS var even if 100vh
computation is good
type: boolean
default: true
Automatically bind to orientationchange
event
type: boolean
default: false
Change the CSS var value.
Instead of being the total size of the gap, it will be 1% of the real window size.
You can find more explanation in this CSS Trick article
If you don't set a cssVarName
, the CSS custom property will be named vh
instead of vh-offset
.
So your CSS should be:
.my-element {
height: 100vh;
height: calc(var(--vh, 1vh) * 100);
}
type: boolean
default: false
Add an event listener on touchmove
to recompute the sizes
- This can impact your website performances as changing sizes will make your browser reflow
- if
options.bind
isfalse
, this will be ignored as well
type: function
default: function noop(){}
you can specify a callback which will be called with an updated vh-check
object every time a computation occurre.
This library require requestAnimationFrame which is IE10+ You'll need a polyfill if you want to support older browsers
- vh unit – supported since IE9+
- calc – supported since IE9+
- CSS custom properties – supported since IE Edge and iOS 9.3+ IE11 & below will need a fallback without CSS var
- concerned browsers – as for now:
- Safari since iOS7+
- Chrome Android >= v56
To sum it up:
Browser | Library will work | CSS Custom property |
---|---|---|
<= IE 9 | ❌ | ❌ |
IE 10 & IE 11 | ✅ | ❌ |
IE Edge | ✅ | ✅ |
< iOS 9.3 | ✅ | ❌ |
https://hiswe.github.io/vh-check/
you'll need node
- clone the project
npm install
npm start
- go to: http://localhost:8080
On iOS only, Chrome & Firefox will change dynamically the size of 1vh
depending on the display of the address bar.
Thus the library will return a not needed
value.
If you want to prevent your vh's components to resize, you could fix the size of the unit like this:
vhCheck({
bind: false,
redefineVh: true,
})
.my-div {
height: calc(var(--vh, 1vh) * 100);
}
See CHANGELOG.md
See MIGRATING.md
- clone the project
npm install
npm test
- Chris Butterworth for the contribution