Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

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 useheight:100vh for fullscreen layout which is easy hack and convenient way to get better design.

Example

.content{height:100vh;}
Enter fullscreen modeExit 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 thewindow.innerheight property.

constdocumentHeight=()=>{constdoc=document.documentElementdoc.style.setProperty('--doc-height',`${window.innerHeight}px`)}window.addEventListener(resize,documentHeight)documentHeight()
Enter fullscreen modeExit 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 modeExit 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

Top comments(45)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
joelbonetr profile image
JoelBonetR 🥇
Tech Lead/Team Lead. Senior WebDev.Intermediate Grade on Computer Systems-High Grade on Web Application Development-MBA (+Marketing+HHRR).Studied a bit of law, economics and design
  • Location
    Spain
  • Education
    Higher Level Education Certificate on Web Application Development
  • Work
    Tech Lead/Lead Dev
  • Joined

You never should use static measurements to set aheight nor awidth unless it's completely necessary.

On the other hand, usingmin-height: 100vh; is totally Ok.
Or:

height:100vh;overflow-y:scroll;
Enter fullscreen modeExit fullscreen mode

depending on what you want to achieve

CollapseExpand
 
ivan_jrmc profile image
Ivan Jeremic
Web/Software Developer
  • Joined

window innerHeight is safer and there are observers which you can use, I have a powerful React hook which does this, using 100vh is unsafe to use and very likely to break in some browsers.

CollapseExpand
 
joelbonetr profile image
JoelBonetR 🥇
Tech Lead/Team Lead. Senior WebDev.Intermediate Grade on Computer Systems-High Grade on Web Application Development-MBA (+Marketing+HHRR).Studied a bit of law, economics and design
  • Location
    Spain
  • Education
    Higher Level Education Certificate on Web Application Development
  • Work
    Tech Lead/Lead Dev
  • Joined
• Edited on• Edited

I'm not supporting IE since long time ago plus checked the usage for Opera Mini since 5 years ago in multiple webapps in production with hundreds of thousands of users, still got 0%:caniuse.com/viewport-units

Using JavaScript has some drawbacks as well:

  • When using SSR you can not pre-render window/document API-related stuff. So you need to defer this to the client, which usually deals to CLS (Cumulative Layout Shifting) and thus a worse user-experience and a worse score incore web vitals, which lowers your SEO.
  • You need to observe a given identifier to know when it exists, otherwise you can get a "Can't get innerHeight of undefined", which means you add an extra event-listener i.e. resize event.
  • If you use anu Reactive library or framework such React, adding those listeners on a Hook will cause a re-render since the beginning.
  • It's slower than CSS Only approach.

In CSS you can also use a calc to extract the navbar size if not fixed just like that:

.containerElement{min-width:calc(100vh-80px);}
Enter fullscreen modeExit fullscreen mode

Plus using min-height this way lets the content to grow more than a viewport if it's needed automagically (smartphone in landscape is a good test for that).

Note that the first one grows more than a viewport due to its texts getting more space.
The last one is just a viewport height. 😁

Thread Thread
 
ivan_jrmc profile image
Ivan Jeremic
Web/Software Developer
  • Joined

Re-render on window size change is not a problem since this is a very rare event and it really on re-renders on size change. Also Safari mobile has lots of problems with 100vh

Thread Thread
 
joelbonetr profile image
JoelBonetR 🥇
Tech Lead/Team Lead. Senior WebDev.Intermediate Grade on Computer Systems-High Grade on Web Application Development-MBA (+Marketing+HHRR).Studied a bit of law, economics and design
  • Location
    Spain
  • Education
    Higher Level Education Certificate on Web Application Development
  • Work
    Tech Lead/Lead Dev
  • Joined
• Edited on• Edited

Not at all. Issues related with smartphone try to artificially alter the behavior based on observation of the outer picture.

I mean, the browser UI is not part of the DOM, hence it will look the same in any website.

While altering your site based on browser+device makes your webApp consistent across-devices, usually an individual who's used to a given browser or a given device will expect that things to happen.

Moreover converting your WebApp into a PWA or making a native webview for iOS and/or Android, will behave different than opening it in the browser.

So each approach has pros and cons, just need to define whad do you really need for that specific use-case. 😊

Last but not least, let me introduce you to@supports feature query:spec, in which you can add vendor prefixed conditions to know which browser rendered your webApp and thus apply a calc on it like that:

@supports(-moz-appearance:meterbar){/* We're on Mozilla! */min-height:calc(100vh-20px);}
Enter fullscreen modeExit fullscreen mode

Or usingBrowser Hacks:

@mediascreenand(-ms-high-contrast:active),(-ms-high-contrast:none){/* We are on Internet Explorer! */min-height:calc(100vh-10px);}
Enter fullscreen modeExit fullscreen mode

Hope it helps somehow

Thread Thread
 
lexlohr profile image
Alex Lohr
...former musician, voice actor, martial artist, started coding 38 years ago and turned front-end developer 25+ years ago.

Fun fact: I'm actually the guy who came up with the msie10+ detection hack you mention in your last example.

Unfortunately, since the wrongful handling of 100vh in mobile browsers is not by a fixed height, you can only using the maximum deviation to fix the issue, which then results in large parts of the screen being unused.

Also, reading innerHeight and writing it to a CSS variable won't take too much time and CPU cycles; detecting scroll movements that should trigger the issue and removing the listener if it doesn't arise will be much more involved.

Thread Thread
 
joelbonetr profile image
JoelBonetR 🥇
Tech Lead/Team Lead. Senior WebDev.Intermediate Grade on Computer Systems-High Grade on Web Application Development-MBA (+Marketing+HHRR).Studied a bit of law, economics and design
  • Location
    Spain
  • Education
    Higher Level Education Certificate on Web Application Development
  • Work
    Tech Lead/Lead Dev
  • Joined

Sure that last paragraph is what solves any situation I can think off, there's no point of discussion here.

I'm trying to define in my head all the situations in which that makes a real difference and not just a "some pixels extra-scroll" thingy, and asking me "is there any alternative way?" Just because linking information is the way I can remember something for years plus I usualy learn something else while trying to answer the question 😅.

Thread Thread
 
ivan_jrmc profile image
Ivan Jeremic
Web/Software Developer
  • Joined

@joelbonetr I don't support IE too but we have a new IE on the block called Safari which is the worst in implementing standards and compatible APIs. They are literally thinking browsers are not needed anymore and in a few years they are gone and everything is an app...

Thread Thread
 
joelbonetr profile image
JoelBonetR 🥇
Tech Lead/Team Lead. Senior WebDev.Intermediate Grade on Computer Systems-High Grade on Web Application Development-MBA (+Marketing+HHRR).Studied a bit of law, economics and design
  • Location
    Spain
  • Education
    Higher Level Education Certificate on Web Application Development
  • Work
    Tech Lead/Lead Dev
  • Joined

Hahaha I know, they have implemented better flex compat in the last 2 years at least, it was a pain in the ass before that but yes, Safari is the new IE.

I work with Windows 11 + WSLg in my personal desktop and Windows 10 + WSL2 in company's laptop so I bought an iPad mini just to test things in Safari as reference (or in any browser because in iPad OS or iOS all browsers rely on Safari 😐).

Thread Thread
 
reymons profile image
Daniel
  • Joined
• Edited on• Edited

@joelbonetr

When using SSR you can not pre-render window/document API-related stuff. So you need to defer this to the client, which usually deals to CLS (Cumulative Layout Shifting) and thus a worse user-experience and a worse score in core web vitals, which lowers your SEO

Just embed the script before the content like so:

<script>function calcVh() { document.style.setProperty("--100vh", `${window.innerHeight}px`); }calcVh();</script>
Enter fullscreen modeExit fullscreen mode

No issues with SSR and SEO at all.

You need to observe a given identifier to know when it exists, otherwise you can get a "Can't get innerHeight of undefined", which means you add an extra event-listener i.e. resize event.

A drop in the sea. Just add to the script above the following:

window.addEventListener("resize", calcVh);
Enter fullscreen modeExit fullscreen mode
CollapseExpand
 
nirazanbasnet profile image
⚡ Nirazan Basnet ⚡
Exploring the new tools and techniques on frontend development. Loves to meet up with new people and participate in the community. I do interesting stuff on codepen https://codepen.io/nirazanbasnet

Here, I am not using static measurements. From js we can detect the app height and it automatically fits it and when we encounter browsers address bar thenusing 100vh does not solve the problem. In my case, above code doesn't solve the issue. But thanks for the reply.

CollapseExpand
 
joelbonetr profile image
JoelBonetR 🥇
Tech Lead/Team Lead. Senior WebDev.Intermediate Grade on Computer Systems-High Grade on Web Application Development-MBA (+Marketing+HHRR).Studied a bit of law, economics and design
  • Location
    Spain
  • Education
    Higher Level Education Certificate on Web Application Development
  • Work
    Tech Lead/Lead Dev
  • Joined
• Edited on• Edited

Positioning the bottom bar with

position:fixed;left:0;right:0;bottom:0;
Enter fullscreen modeExit fullscreen mode

will fix your nav bar to the bottom without issues, then you can get the scroll to modify it's position to ptovide a js effect or to trigger a keyframe

CollapseExpand
 
esspetess profile image
Yih Sev
  • Location
    Philippines
  • Work
    toptal
  • Joined
• Edited on• Edited

issues on mobile with vh..html, body, .some-page-wrapper { height: 100% } usually works even without JS... for most basic layouts. Then you don't have to use100vh

CollapseExpand
 
joelbonetr profile image
JoelBonetR 🥇
Tech Lead/Team Lead. Senior WebDev.Intermediate Grade on Computer Systems-High Grade on Web Application Development-MBA (+Marketing+HHRR).Studied a bit of law, economics and design
  • Location
    Spain
  • Education
    Higher Level Education Certificate on Web Application Development
  • Work
    Tech Lead/Lead Dev
  • Joined
• Edited on• Edited

min-height: 100vh is meant for when you want some block to have at least the height of the viewport's height. You cannot use % on those situations.
Moreover, height 100% (which means the height of its content without taking into account the padding nor the margin) is the default implicit behavior on any div, section, aside...

Edit: WRONG, see comment below

Thread Thread
 
esspetess profile image
Yih Sev
  • Location
    Philippines
  • Work
    toptal
  • Joined
• Edited on• Edited

I completely understand how 100vh and % works. I think you misunderstood the context of the post. If you meant to make the body 100vh, basically setting the html, and the body to 100% is the same thing as setting the body to 100vh. duhhh! But the thing is, using the % method doesn't give you the issues mentioned in the post when viewing the layout on mobile phones.

ANdI think you misunderstood how height 100% works in the context of my answer. What you are saying is definitely wrong - go test it yourself if setting both html, and body to 100% isn't the same thing as setting the body to 100vh.. maybe you need to learn how setting the height to percentage works if you have set the height of the parent. for a percentage value to work for height, the parent's height must be determined, and in this case setting HTML and the body to 100% does fill the whole viewport height(and yet doesn't cause the issues mentioned on mobile devices)

Thread Thread
 
joelbonetr profile image
JoelBonetR 🥇
Tech Lead/Team Lead. Senior WebDev.Intermediate Grade on Computer Systems-High Grade on Web Application Development-MBA (+Marketing+HHRR).Studied a bit of law, economics and design
  • Location
    Spain
  • Education
    Higher Level Education Certificate on Web Application Development
  • Work
    Tech Lead/Lead Dev
  • Joined

@esspetess oh sorry you're right, I misunderstood the comment (6 months old post 😂). Still you should usemin-height instead ofheight property, otherwise if the content exceeds the container it will overlap with the following container and cause weird effects.

Have a great day

CollapseExpand
 
alohci profile image
Nicholas Stimpson
Full Stack Software Engineer or jobbing programmer.
  • Location
    Luton, England
  • Joined

Coming soon: lv*, sv* & dv* units to address this issue.

CollapseExpand
 
gmutschler profile image
Guillaume M.
  • Joined
• Edited on• Edited

Wow that's interesting.

Until its validation, I wonder how the cssenv() function could be used to solve our 100vh issue. (it already has a quite broad browser support)

CollapseExpand
 
nirazanbasnet profile image
⚡ Nirazan Basnet ⚡
Exploring the new tools and techniques on frontend development. Loves to meet up with new people and participate in the community. I do interesting stuff on codepen https://codepen.io/nirazanbasnet
• Edited on• Edited

Earlier I tried using env() but it doesn't solve my issue so need to revert back.

CollapseExpand
 
nirazanbasnet profile image
⚡ Nirazan Basnet ⚡
Exploring the new tools and techniques on frontend development. Loves to meet up with new people and participate in the community. I do interesting stuff on codepen https://codepen.io/nirazanbasnet

Might be helpful but does not know anything about this so far :)

CollapseExpand
 
ben profile image
Ben Halpern
A Canadian software developer who thinks he’s funny.
  • Email
  • Location
    NY
  • Education
    Mount Allison University
  • Pronouns
    He/him
  • Work
    Co-founder at Forem
  • Joined

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 aslightly 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. 🙂

CollapseExpand
 
nosovandrew profile image
Andrew Nosov
Creating web e-commerce projects
  • Location
    Russia
  • Work
    Entrepreneur
  • Joined

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.

lettimeoutId=null;constdocumentHeight=()=>{clearTimeout(timeoutId);// avoid execution of previous timeoutstimeoutId=setTimeout(()=>{constdoc=document.documentElement;doc.style.setProperty('--doc-height',`${window.innerHeight}px`)},200);};window.addEventListener(resize,documentHeight);documentHeight();
Enter fullscreen modeExit fullscreen mode
CollapseExpand
 
nirazanbasnet profile image
⚡ Nirazan Basnet ⚡
Exploring the new tools and techniques on frontend development. Loves to meet up with new people and participate in the community. I do interesting stuff on codepen https://codepen.io/nirazanbasnet

Tankyou !! Appreciated :)

CollapseExpand
 
greggcbs profile image
GreggHume
A developer who works with and on some of the worlds leading brands. My company is called Cold Brew Studios, see you out there :)
  • Joined

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

CollapseExpand
 
endymion1818 profile image
Ben Read
I don’t know enough. Software Engineer, JavaScript mostly. Interested in DevOps
  • Email
  • Location
    Flintshire
  • Education
    School of Life
  • Work
    Web developer
  • Joined

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 youknow 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”.

CollapseExpand
 
ryanpearson profile image
Ryan Pearson
Font end dev in San Diego
  • Work
    UX Front End Developer
  • Joined
• Edited on• 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)

CollapseExpand
 
nirazanbasnet profile image
⚡ Nirazan Basnet ⚡
Exploring the new tools and techniques on frontend development. Loves to meet up with new people and participate in the community. I do interesting stuff on codepen https://codepen.io/nirazanbasnet

Thanks for using this solution 👍

CollapseExpand
 
leob profile image
leob
  • Joined

Meaning, most people are doing this wrong? Or maybe most people already know this?

CollapseExpand
 
nirazanbasnet profile image
⚡ Nirazan Basnet ⚡
Exploring the new tools and techniques on frontend development. Loves to meet up with new people and participate in the community. I do interesting stuff on codepen https://codepen.io/nirazanbasnet

Due to browser dependencies and layout issue we need to tackle this kind of problem so it depends on project requirement. But, I suggest not to use100vh on smaller devices.

CollapseExpand
 
andrewbaisden profile image
Andrew Baisden
Software Developer | Content Creator | AI, Tech, Programming
  • Location
    London, UK
  • Education
    Bachelor Degree Computer Science
  • Work
    Software Developer
  • Joined

Many ways to solve the same problem.

CollapseExpand
 
liviufromendtest profile image
Liviu Lupei
Focused on Automated Testing.
  • Location
    Bucharest, Romania
  • Work
    Solutions Architect at Endtest
  • Joined

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

CollapseExpand
 
nirazanbasnet profile image
⚡ Nirazan Basnet ⚡
Exploring the new tools and techniques on frontend development. Loves to meet up with new people and participate in the community. I do interesting stuff on codepen https://codepen.io/nirazanbasnet

Thank you 👍

CollapseExpand
 
ambriel profile image
Ambriel Goshi
  • Joined

This is helpful.

CollapseExpand
 
nirazanbasnet profile image
⚡ Nirazan Basnet ⚡
Exploring the new tools and techniques on frontend development. Loves to meet up with new people and participate in the community. I do interesting stuff on codepen https://codepen.io/nirazanbasnet

Thanks 👍

CollapseExpand
 
kelseyjj profile image
Kelsey Jones
  • Joined

Glad I came across this.

CollapseExpand
 
nirazanbasnet profile image
⚡ Nirazan Basnet ⚡
Exploring the new tools and techniques on frontend development. Loves to meet up with new people and participate in the community. I do interesting stuff on codepen https://codepen.io/nirazanbasnet

Thanks 👍

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

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Exploring the new tools and techniques on frontend development. Loves to meet up with new people and participate in the community. I do interesting stuff on codepen https://codepen.io/nirazanbasnet
  • Location
    Kathmandu, Nepal
  • Education
    Be IT
  • Joined

More from⚡ Nirazan Basnet ⚡

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp