1

Here is a minimal example of the CSS footer trick:

body {
  margin: 0;
  font-size: 1rem;
}

#wrapper {
  display: grid;
  grid-template-rows: auto 1fr auto;
  height: 100vh;
  /* make the font size a little bigger */
  font-size: 2rem;
  font-family: Helvetica, Arial, sans-serif;
  width: 100vw;
  grid-template-columns: 1fr;
}

header, footer {
  text-align: center;
}
<div id="wrapper">
  <header>This is the header</header>
  <main>This is the main content</main>
  <footer>This is the footer</footer>
</div>

If you open this up in a desktop browser, it works as expected. However, in every mobile browser I tested (Chrome, Firefox, Safari), the footer is invisible (you have to scroll to see it). Why is this the case?

Note that if you're trying out this example on desktop with developer tools device emulator, try setting the display size to iPhone 12 Pro and Zoom to 100% instead of using the "Responsive" device. This will best show how it actually looks on mobile.

EDIT: it does work properly on mobile Firefox, which begs the question why it doesn't on Chrome and Safari

Kameron
  • 10,240
  • 4
  • 13
  • 26
Daniel Kats
  • 5,141
  • 15
  • 65
  • 102
  • 2
    Pretty sure it has to do with `100vh` not being consistant on mobile browsers, see related questions: https://stackoverflow.com/questions/37112218/css3-100vh-not-constant-in-mobile-browser – Félix Paradis Aug 11 '22 at 17:57
  • 1
    Can you try to set the height of the body and the wrapper to 100% please? – Akis Aug 11 '22 at 18:00
  • @Akis that doesn't work and actually ruins the formatting on desktop as well – Daniel Kats Aug 11 '22 at 18:09
  • @FélixParadis I think you're right. What's the recommended workaround? Based on the question you linked there is no fixed planned – Daniel Kats Aug 11 '22 at 18:09

1 Answers1

2

This is because on mobile browsers there is roughly 10vh of space reserved for the browser navigation tools. (depending on browser)

If you're shooting for 100vh you can use javascript to instruct the element to take all of the available window.innerHeight, which will account for these mobile navigation tools on all browsers.

function resetHeight() {
  // reset the #wrapper height to that of the inner browser
  document.getElementById('wrapper').style.height = window.innerHeight + "px";
}
// reset the height whenever the window's resized
window.addEventListener("resize", resetHeight);
// called to initially set the height.
resetHeight();
body {
  margin: 0;
  font-size: 1rem;
}

#wrapper {
  display: grid;
  grid-template-rows: auto 1fr auto;
  /* make the font size a little bigger */
  font-size: 2rem;
  font-family: Helvetica, Arial, sans-serif;
  width: 100vw;
  grid-template-columns: 1fr;
}

header,
footer {
  text-align: center;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title></title>
</head>

<body>
  <div id="wrapper">
    <header>This is the header</header>
    <main>This is the main content</main>
    <footer>This is the footer</footer>
  </div>
</body>

</html>

If you open your dev tools and change the height of the browser you'll notice the height of #wrapper responsively changing with it.

Kameron
  • 10,240
  • 4
  • 13
  • 26
  • Was the `function` attribute on #wrapper deliberate? I've never seen that before. – Daniel Kats Aug 11 '22 at 18:22
  • @DanielKats It was not actually. Typically when I use this script I use it on `body` because I use it for pages with no intended scroll. In the event that you used `document.body.style.height = window.innerHeight + "px";` then you would need the function the `body` element. – Kameron Aug 11 '22 at 18:30