CSS3 100vh not constant in mobile browser
Unfortunately this is intentional…
This is a well know issue (at least in safari mobile), which is intentional, as it prevents other problems. Benjamin Poulain replied to a webkit bug:
This is completely intentional. It took quite a bit of work on our part to achieve this effect. :)
The base problem is this: the visible area changes dynamically as you scroll. If we update the CSS viewport height accordingly, we need to update the layout during the scroll. Not only that looks like shit, but doing that at 60 FPS is practically impossible in most pages (60 FPS is the baseline framerate on iOS).
It is hard to show you the “looks like shit” part, but imagine as you scroll, the contents moves and what you want on screen is continuously shifting.
Dynamically updating the height was not working, we had a few choices: drop viewport units on iOS, match the document size like before iOS 8, use the small view size, use the large view size.
From the data we had, using the larger view size was the best compromise. Most website using viewport units were looking great most of the time.
Nicolas Hoizey has researched this quite a bit: https://nicolas-hoizey.com/2015/02/viewport-height-is-taller-than-the-visible-part-of-the-document-in-some-mobile-browsers.html
No fix planned
At this point, there is not much you can do except refrain from using viewport height on mobile devices. Chrome changed to this as well in 2016:
- https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/BK0oHURgmJ4
- https://developers.google.com/web/updates/2016/12/url-bar-resizing
Safari + CSS: using calc with vh does not work
Safari seems to be kind of buggy with viewport units in general, especially if you go back a version or two. The last time I tried to use vh/vw, I ran into similar issues and ended up making use of the v-unit javascript micro-lib, and it worked out very well.
CSS is rapidly catching up to javascript for things like layout calculations, but when it gets complex, supplementing your css with some light scripting often works better than CSS alone.
CSS 100vh is too tall on mobile due to browser UI
Usually the 100vh
height will account for the adjusted height, with is why you'll sometimes see mobile pages go funky when the browser's address bar slides down.
For browsers that don't account for the sliding bar within the vh
unit: The height for the address bars will not be constant across the browsers, so I'd advise against appending -50px
.
Try setting the height of the page (using javascript) with the window.innerheight
property.
function resetHeight(){
// reset the body height to that of the inner browser
document.body.style.height = window.innerHeight + "px";
}
// reset the height whenever the window's resized
window.addEventListener("resize", resetHeight);
// called to initially set the height.
resetHeight();
How to set fixed base to calculate vh unit in css on mobile?
Finally I used jQuery to fix vh units, as it was mentioned in source 2 and there.
CSS: Are view height (vh) and view width (vw) units widely supported?
Safari Viewport Bug, Issues with Fixed Position and Bottom or Top
Hello this question kind of got me at first and I thought back to my days poking around in HTML and CSS for hours on end trying to get things right. Alas all those hours of missery have been for this moment.
vh
used to be calculated by the current viewport of your browser. If you loaded a site in your browser, 1vh
would be the same as 1% of your screen height, and then minus the browser interface.
But! If you wanted to scroll, it gets tricky. Once you brush past the browser interface (in this case your address bar), you would have a wierd jump in your content because the vh
would be updated.
Safari for iOS was actually was one of the first to implement a fix. They set a fixed vh
value based on the max screen height. Then the user wouldn't experience the jump in content, but .... yup, there's always a but...
Having the fixed value is awesome, except when you wanna have a full sized element, or an element with fixed position at the bottom of the screen because then it would get cropped out!
That is your problem....and say goodbye to it, because...
This is your solution!!
css:
.my-element {
height: 100vh; /* This is for browsers that don't support custom properties */
height: calc(var(--vh, 1vh) * 100);
}
js:
// Get the viewport height and multiply it by 1% to get a value for a vh unit
let vh = window.innerHeight * 0.01;
// Then set the custom --vh value to the root of the document
document.documentElement.style.setProperty('--vh', `${vh}px`);
Now you can use --vh as your height value like we would any other vh unit, multiply it by 100 and you have the full height we want.
One thing left, the js up there runs, but we never update the element's size when the viewport changes, so that wouldn't work yet, you need a listener...
more js:
// We listen to the resize event
window.addEventListener('resize', () => {
// Update the element's size
let vh = window.innerHeight * 0.01;
document.documentElement.style.setProperty('--vh', `${vh}px`);
});
Cheers!
Calc function with vh and px does not work in safari
See Caniuse, also look at this SO question
Safari & iOS Safari (both 6 and 7) does not support viewport units for
border widths, column gaps, transform values, box shadows or in
calc().
Related Topics
How to Float an Element Left with Full Height of the Wrapper
Shared Styles Across Components in an Angular 2 App
Using '-Webkit-Overflow-Scrolling: Touch' Hides Content While Scrolling/Dragging
Anyway to Have a Label Respond to :Focus CSS
Gradient Color in a Treemap for D3
Show :After When Hovering Over the Parent Element via CSS
Css3 White to Transparent Gradient
How to Get Only One Rounded Corner with Border-Radius Htc Hack and Msie V:Roundrect
Background Images Path in SASS and Compass
How to Hide Default Choose File Button
Bootstrap 4, Bg-Inverse Not Showing
Using CSS to Duplicate HTML Elements