As you see, the web content will be outside the viewport although we used 100vh
(the red opacity box with 100vh
text).
.section {
height: 100vh; // bad approach
}
This problem we will receive when we just put height: 100vh
for mobile devices. Mobile device calc all browser(top bar + document + bottom bar) as 100vh
, and it’s little annoying when we must have 100vh page, unfortunately it doesn’t work like on desktop browser and we have to make a little more effort to receive the same result.
The 100vh problem on mobile devices is really annoying, everyone knows. I have a simple recipe to solve that problem.
To solve this problem, we need a JS and a CSS or just only the CSS (in the second solution):
1. JS & CSS solution
Let’s get started from JS file:
const appHeight = () => {
const doc = document.documentElement
doc.style.setProperty('--app-height', `${window.innerHeight}px`)
}
window.addEventListener('resize', appHeight)
appHeight()
appHeight function set new style property with var(--app-height
) with the current window height, this property we can use in the CSS file.
:root {
--app-height: 100%;
}
html,
body {
padding: 0;
margin: 0;
overflow: hidden;
width: 100vw;
height: 100vh;
height: var(--app-height);
}
var(--app-height)
— it’s a reference to --app-height
variable that we created previously in a JS file.
2. CSS solution (not recomended)
The second solution is --webkit-fill-available
this will ignore safari and iOS native bars, and fill only the document view, but this solution doesn't protect us at Android devices.
height: 100%;
height: -webkit-fill-available;
Thank you for your attention! I’ll appreciate your feedback.
If you like this article, follow me on Twitter @MaciejDEV
Discussion (9)
My approach is to disable the show/hide of the safari bars by preventing the body from scrolling. That way the content area height is constant.
Hi, It will work, but you have to remember about for example scrollTo and #anchors in this solution.
nice! thanks for posting, this is the most effective solve I've found.
something thing I noticed after implementing this solution is that it can trigger the fabled 'jumpy scroll', referenced in the stack overflow post I'm sure we all landed on before finding this post. stackoverflow.com/questions/371122...
as a workaround I created two css variables, one for the fixed "starting" height, and another "dynamic" height that is only used for the shopping cart, mobile menu and other fixed-position elements that require 100% screen height.
pasted below in case someone else runs into the same issue!
// set up css var for starting app height. this will not change on resize so we can avoid the jumpy scroll issue
const appHeight = () => {
const doc = document.documentElement;
doc.style.setProperty('--app-height',
${window.innerHeight/10}rem
)};
window.addEventListener('orientationchange', appHeight);
appHeight();
// set up css var for dynamic app height. this is just for the cart and mobile menu since they need to be fixed to size at all times.
const dynamicAppHeight = () => {
const doc = document.documentElement;
doc.style.setProperty('--dynamic-app-height',
${window.innerHeight/10}rem
)};
window.addEventListener('resize', dynamicAppHeight);
dynamicAppHeight();
Hi,
see: dev.to/admitkard/mobile-issue-with...
Same issue, but again - on current Safari it is NOT working! Even on Android devices, I see the same issue.
So is there a working solution if the address bar moves away (no resize/switch to landscape etc.).
I’m confused 🤣
So what are you saying? That the JS solution in this thread doesn’t work but the one you linked does?
Hi could you please also illustrate the problem? thanks!
Hi clivend,
Yes, sure I will illustrate the problem today/tomorrow. Thanks for letting me know what is missing!
Actually, it's not only on safari. I had the exact same problem on chrome / brave and used the first solution for one of my latest projects ;)
Hi ips-coding-challenge,
yes, you are right, I missed issue with OnePlus what I had last year. 🙏