I noticed a discrepancy between Chrome and Firefox on Android.

In my WordPress theme Cover2 (which powers this website), featured images on posts and pages are full 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 (Firefox is on the left, Chrome is on the right):

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 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, including both Chrome and Firefox on Android. 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.