loading...

100vh behavior on Chrome

peiche profile image Paul ・3 min read

In one of my WordPress themes, featured images on posts and pages fill the screen. They serve as a background image, with the title vertically and horizontally centered. At the bottom of the screen, there is a little arrow icon that you can click (or tap, if you’re on a touch device) which will trigger a scroll to the start of the page.

In the CSS, the 100% height is achieved with this:

min-height: 100vh;

(I had originally used height, but I found that long titles would get cut off on small screens, like on phones and tablets. By using min-height, I was able to ensure that long titles would simply push the height to larger than 100% if they needed to.)

The problem

Since Cover2 is a responsive theme, I try to make sure that it looks good across browsers and screen sizes. It was brought to my attention that in Chrome on Android that this was not the case.

Both Firefox and Chrome on Android do this thing where as you scroll down, the browser’s address bar slides up until you scroll back up, and then it comes into view again. (This is actually just like Cover2’s implementation of its own navbar.) The browsers treat the screen height differently, though.

In Firefox, when the address bar is visible, the full height (100vh in CSS) is the height between the address bar and the bottom of the screen.) When the address bar is hidden, the full height is the height between the top and bottom of the screen.

In Chrome, the full height is the height between the top and bottom of the screen, whether the address bar is visible or not.

The solution

I’ve written before on how much I dislike user agent sniffing. (Funny side note: I recently discovered that my wife finds that term hilarious.) This is one case, however, where I don’t think I can get around it.

The solution is to reduce the full-screen height for Chrome, so that the address bar isn’t taken into consideration. The height of the address bar is 56px (as far as I’m able to tell through trial and error), but I still need to target only Chrome on Android.

WordPress already does some user agent sniffing, and it assigns classes to the <body> tag with what it finds. For example, on my computer, it assigns the classes os-windows and browser-gecko (that’s Firefox, in case you’re wondering.) But here’s the problem: WordPress assigns the class browser-android for every browser on Android, including Chrome and Firefox, not just the stock browser that used to come with Android before Chrome became the de facto standard. That obviously won’t work, so I needed to find something more specific. Enter the CSS @supports at-rule.

I much prefer feature queries, so I use @supports in conjunction with a Chrome-specific browser hack. This by itself will target Chrome, Safari, Edge, and Opera, so I combine it with the WordPress-powered user agent OS class:

.page-header {
  @supports (-webkit-appearance:none) {
    .os-android & {
      min-height: calc(100vh - 56px);
    }
  }
}

And with that, we have proper full height behavior with Chrome’s navbar.


This post was originally published on eichefam.net.

Discussion

markdown guide
 

Another approach that seems to work is to put height:100% on all parent elements up to and including the body and the html elements.

 

Thanks! Thought it wasn't going to work but I went through each parent element (up to html) in devtools and added height: 100%, and it worked :-).

 

I think this is actually the best way to do it without extra hacks for all platforms / screen types.

 

Just came across this "bug" as well. For anyone coming across this article looking for solutions, there is actually a (closed) ticket on the Chrome issue tracker bugs.chromium.org/p/chromium/issue....

I managed to solve the issue by using percents rather than vh. body and html have 100% height and this percent height is defined to be the smallest viewport in Chrome (which is the viewport when the 56px navigation bar is shown) contrary to 100vh which is the largest viewport (when the navigation bar is hidden).

Not sure it'll work in all cases, but for my particular case it worked fine and seems more safe than handling this special case through browser hacks :)

 

Cool article, I´ve bumped into this problem at least once a year. I´m never happy with the solution that work, but in the end I´m happy to have anything that works.

And I still don´t understand why min-height:100% on the

element does not work (given that html is indeed 100% height).

thanks for the article.

 

Came here for the solution, stayed to necropost. 😏

The reason 100% doesn't work is because % is a VERY relative measurement. 100% of what?

If your hero image is nested at all then 100% refers to the patent container's height.

VH & VW are absolute measures. X/100ths of the viewport height or width. Period.

Make sense?

 

I cannot believe Chrome is not taking the same approach as Firefox with this.

 

This seemed like such an obscure glitch at first, since I couldn't find anything until the right keywords. I just couldn't understand why it looked fine in the desktop, even using the responsive design view on Chrome, yet on mobile it kept messing up. As you can see, it's 2020 and the issue persists (Chrome 81.0.4), so it must be very low priority to them.
Thank you for this.

 

Hi my friend and thank you for your article, sorry for the noob question can you please explain to me where to put your code in my wordpress site? I'm developing the site with divi and I have a simple section with a full screen background using 100vh, then I have some buttons that I want to stay in the bottom of this background, no problems with any browser but with chrome the buttons are not visible until I scroll down due the address bar size as you explained in your article. I can't understand how to implement your code. many thanks for your help

 

Unfortunately tablets have even higher navbar with tabs and such like on desktop.