DEV Community

Cover image for Don't use 100vh for mobile responsive
⚡ Nirazan Basnet ⚡
⚡ Nirazan Basnet ⚡

Posted on

Don't use 100vh for mobile responsive

Generally, we use height:100vh for fullscreen layout which is easy hack and convenient way to get better design.

Example

.content {
   height: 100vh;
}
Enter fullscreen mode Exit fullscreen mode

But when we test our design on actual device, we encounter several issues:

  • Mostly Chrome and Firefox browsers on mobile have got a UI (address bar etc) at the top.
  • On Safari it get's more tricky address bar is at the bottom.
  • Different browsers have different sized viewports
  • Mobile devices calc browser viewport as (top bar + document + bottom bar) = 100vh
  • Whole document is filled to the page using 100vh

Problems

  • On Chrome

Chrome 100vh issue

Scrollbar issues has been detected. Bad user flow and difficult to navigate the content.

Note: I have also tested this issues on safari which makes more bad user flow


Solutions

Detect the height of the app by using JS

Setting the height of the page (using javascript) with the window.innerheight property.

const documentHeight = () => {
 const doc = document.documentElement
 doc.style.setProperty('--doc-height', `${window.innerHeight}px`)
}
window.addEventListener(resize, documentHeight)
documentHeight()
Enter fullscreen mode Exit fullscreen mode

Using, CSS Variable

:root {
 --doc-height: 100%;
}

html,
body {
 padding: 0;
 margin: 0;
 height: 100vh; /* fallback for Js load */
 height: var(--doc-height);
}
Enter fullscreen mode Exit fullscreen mode

Here, documentHeight function sets new style property var('--doc-height') and includes current window height.


Final Results

Chrome Browser

CSS 100vh viewport

Note: There is no any vertical extra scrollbar is appearing now also no issues on Safari too. The bottom address bar of safari is always on the bottom which makes good user flow to the website


Conclusion
👏👏 By coming this far I hope you can solve the mobile devices viewport issues. So, I suggest you give it a try on your project and enjoy it!

Feel free to share your thoughts and opinions and leave me a comment if you have any problems or questions.

Till then,
Keep on Hacking, Cheers

Latest comments (45)

Collapse
 
greggcbs profile image
GreggHume

For anyone using react, i wouldnt waste time with any css solutions. Use this react hook and be done with it:
usehooks-ts.com/react-hook/use-win...

Collapse
 
piarey profile image
piarey

!!!!! This solution still has serious problems. !!!!!

1.
(iOS 15.2)
(when the content length is less than the viewport height)
"When the swipe down refresh function is exposed" ===>>> This action triggers the "Resize" event.

In other words, if you keep trying to swipe down, the continuously calculated height value will decrease, eventually creating a blank space at the bottom.

2.
What if the length of the content is between height: 100% and 100vh???
(iOS15.0.2) 100vh - A blank space is created at the bottom as much as the length of the content.

==========

Even so, are you still going to treat this situation as normal?
iOS is the re-advent of IE.

Collapse
 
balchen profile image
balchen

I'm experiencing the exact same problem, and came across this post (among many others on the same subject). While it does fix the issue for Android and iOS devices, it breaks the page for desktop (Chrome and Firefox, at least).

The scrollbar I don't want now appears on desktop.

If I subtract 1px from innerHeight in the code, there's no scroll bar on desktop. It's a hack. Don't know why 1px makes the difference in this case.

Collapse
 
lico profile image
SeongKuk Han

Thank you! It worked for me!

Collapse
 
nirazanbasnet profile image
⚡ Nirazan Basnet ⚡

Glad this helped you

Collapse
 
kelseyjj profile image
Kelsey Jones

Glad I came across this.

Collapse
 
nirazanbasnet profile image
⚡ Nirazan Basnet ⚡

Thanks 👍

Collapse
 
ambriel profile image
Ambriel Goshi

This is helpful.

Collapse
 
nirazanbasnet profile image
⚡ Nirazan Basnet ⚡

Thanks 👍

Collapse
 
rasmrq profile image
Pace Dev

So thanks uuu

Collapse
 
ibenchellali profile image
IDRESS BENCHELLALI

Thank you for this great article!

Collapse
 
nirazanbasnet profile image
⚡ Nirazan Basnet ⚡

Your welcome :)

Collapse
 
nosovandrew profile image
Andrew Nosov

Cool solution, it helped me, thank you! In addition I've improved this approach with some debounce mechanism (setTimeout) that will limit count of function executions.

let timeoutId = null;
const documentHeight = () => {
  clearTimeout(timeoutId); // avoid execution of previous timeouts
  timeoutId = setTimeout(() => {
   const doc = document.documentElement;
   doc.style.setProperty('--doc-height', `${window.innerHeight}px`)
  }, 200);
};
window.addEventListener(resize, documentHeight);
documentHeight();
Enter fullscreen mode Exit fullscreen mode
Collapse
 
greggcbs profile image
GreggHume

Sometimes debouncing cost more then running the code itself. Just as an FYI.

Collapse
 
nirazanbasnet profile image
⚡ Nirazan Basnet ⚡

Tankyou !! Appreciated :)

Collapse
 
andrewbaisden profile image
Andrew Baisden

Many ways to solve the same problem.

Collapse
 
thebronxsystem profile image
Info Comment hidden by post author - thread only accessible via permalink
thebronxsystem

sick of this trend of people going against a convention just for clicks trying to sound intelligent. its pathetic.

Collapse
 
endymion1818 profile image
Ben Read

So this is a bit of a heated topic isn’t it?! Whilst I applaud your ingenuity I’d be careful about doing this kind of thing with JsS, or as some users suggest, doing a calc- because that assumes you know the height of that element.

Instead use -webkit-fill-available

Here’s some more information about that css rule: allthingssmitty.com/2020/05/11/css...

This situation is far from ideal and I know the Safari team are working hard to address these issues so they don’t become “the next IE”.

Collapse
 
ryanpearson profile image
Ryan Pearson • Edited

This is a good option if you DONT need to use css Calc() function
ex:

body {
min-height: calc(100vh-70px);
/* mobile viewport bug fix */
min-height: -webkit-fill-available;
}

The webkit solution would not take into account the 70px adjustment

I've used the JS solution described in this post and it seems to be the best available option at the moment (until the new dynamic viewport units are adopted)

Collapse
 
nirazanbasnet profile image
⚡ Nirazan Basnet ⚡

Thanks for using this solution 👍

Collapse
 
liviufromendtest profile image
Liviu Lupei

Nicely done for thinking of cross-browser issues.
I'm using Safari on my phone.

Collapse
 
nirazanbasnet profile image
⚡ Nirazan Basnet ⚡

Thank you 👍

Collapse
 
ben profile image
Ben Halpern

This seems like a really useful pattern for using CSS variables in general. Thanks for the post.

Of course, for a lot of use cases the added complexity might not be worth the UX wins vs a slightly alternative design choice. Ultimately it's about helping the user do a thing they came to do, and roundabout complexity isn't exactly helping all the time. But figuring that out and agreeing on it with the designer is easier said than done!

IMO this sort of thing is best approached with a sense of repeating this pattern consistently where needed for styling to ensure it's not a one-off. 🙂

Some comments have been hidden by the post's author - find out more