Search code examples
csssassflexboxfootersticky-footer

Sticky flexbox footer not fixed to bottom


I'm wanting to fit the entire UI on the screen onLoad but my footer is not fixing to the bottom of the view on mobile.

On a desktop web browser, it works perfectly. When I view this on a mobile web browser, the footer is further down the page which makes the page scrollable. It should not scroll, instead, it should fit perfectly inside the viewport.

I've made sure to use the correct meta viewport tag. Included prefixes where I use flexbox. I tried using relative positioning but still not getting the results I want.

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

html,
body {
  font-family: 'Roboto', sans-serif;
}

.container {
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  height: 100%;
  min-height: 100vh;
  flex-direction: column;
  max-width: 420px;
  margin: 0 auto;
  padding: 1rem 1rem 0 1rem;
}

header {
  margin: 2rem 0;
}

main {
  -webkit-box-flex: 1;
  -moz-flex: 1;
  -ms-flex: 1;
  -webkit-flex: 1;
  flex: 1;
}

footer .btn-group {
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  margin-bottom: 1rem;
  margin-top: 0.5rem;
}
<head>
  <meta charset="UTF-8">
  <meta name='viewport' content='width=device-width, initial-scale=1.0'>
  <link rel="stylesheet" href="styles.css">
</head>

<body>
  <div class="container">
    <header>
      <h1 class="title">Title</h1>
    </header>
    <main>
      <div class="list">
        <input type="text">
        <input type="text">
      </div>
    </main>
    <footer>
      <div class="btn-group">
        <button class="btn-refresh">
                    Refresh
                </button>
        <button class="btn-add">
                    Add New
                </button>
      </div>
      <button class="btn">Main Action</button>
    </footer>
  </div>
</body>

On mobile, I'd expect that the footer is fixed to the bottom of the browser viewport, however, the button group is a bit past and a user would need to scroll to see the full group of buttons.

When looking at my codepen version, this works fine. However, when I copy&paste the code to my server the footer does not stay at the bottom.

Is there anything that I am missing?


Solution

  • Note that on some mobile browsers, if an item's height is 100vh you will need to scroll down so see it in its entirety. This is intentional, and it has to do with the visible area changing as you scroll (for example in a lot of mobile browsers like Chrome, the toolbar at the top goes away when you scroll down):

    This is completely intentional. It took quite a bit of work on our part to achieve this effect. :)

    The base problem is this: the visible area changes dynamically as you scroll. If we update the CSS viewport height accordingly, we need to update the layout during the scroll. Not only that looks like shit, but doing that at 60 FPS is practically impossible in most pages (60 FPS is the baseline framerate on iOS).

    It is hard to show you the “looks like shit” part, but imagine as you scroll, the contents moves and what you want on screen is continuously shifting.

    Dynamically updating the height was not working, we had a few choices: drop viewport units on iOS, match the document size like before iOS 8, use the small view size, use the large view size.

    From the data we had, using the larger view size was the best compromise. Most website using viewport units were looking great most of the time.

    If you're looking for a way to circumvent this behavior, I suggest you read this: The trick to viewport units on mobile.