On Safari Mobile 10.3 sticky footer can be scrolled off the screen

11,469

Solution 1

There is nothing you can do about it. Safari's landscape mode makes the container with your content going off the screen. This is not detectable and therefore not to solve. I tried to illustrate what happens:

The blue bar = Safari's navigation bar

The yellow bar = Your app's navigation bar

Situation safari

Instead of shrinking the container's height, Safari lets it go off the screen.

Solution 2

This is more a workaround than a real solution. However position: fixed has been a problem for mobile devices for years and the best way to overcome this problem is to use position: sticky.

sticky behaves like position: relative within its parent, until a given offset threshold is met in the viewport.

From: Stick your landings! position: sticky lands in WebKit

However position: sticky is not fully supported yet, so I would suggest to use also:

position: sticky; /* currently in development for MS Edge */
position: -webkit-sticky;
position: -moz-sticky;
position: -o-sticky;

See status here for MS Edge sticky support status (thank you Frits)

enter image description here


html,
body {
  height: 200%;
}

body {
  background-image: linear-gradient(180deg, #ededed 0px, #ededed 9px, #000000 9px, #000000 10px);
  background-size: 100% 10px;
}

footer {
  position: sticky; /* currently in development for MS Edge */
  position: -webkit-sticky;
  position: -moz-sticky;
  position: -o-sticky;
  height: 50px;
  top: 80%;
  background: rgba(255, 0, 0, 0.7);
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>

<body>
  <footer>
  </footer>
</body>

</html>

Solution 3

There is another way of creating a fixed element at the bottom of the page:

Set the <body> element (or whatever wraps your header, content and footer) to display: flex; height: 100vh. Then you take the footer and set it to margin-top: auto.

HTML:

<body>
    <header>
    </header>
    <main>
    <main>
    <footer>
    </footer>
</body>

CSS:

html {
    height: 100%;
}

body {
    height: 100%;
    display: flex;
    flex-direction: column;
}

main {
    flex: 1;
}

A different solution with the same markup would be to use CSS Grid:

html {
    height: 100%;
}

body {
    height: 100%;
    display: grid;
    grid-template-rows: auto 1fr auto;
}

In order to get the best of both worlds you can wrap the CSS Grid styles in an @supports(display: grid){} wrapper. If Grid is supported the browser will take that and otherwise will fallback to Flexbox.

The best thing using this technique is that you won't run into overlapping contents, into zooming-issues and it is fully responsive from the get-go.

There is an article on CSS Tricks about the subject: https://css-tricks.com/couple-takes-sticky-footer/

Share:
11,469
Andriy Horen
Author by

Andriy Horen

Updated on June 05, 2022

Comments

  • Andriy Horen
    Andriy Horen almost 2 years

    Our mobile web application has sticky bottom navigation like the one you often find in iOS applications, and after Safari 10.3 release on landscape only it is possible to scroll sticky navigation (footer) off the screen. Even though it is position: fixed and set bottom: 0 it also wasn't possible on older Safari versions.

    Styles for sticky nav / footer are following:

    footer {
      position: fixed;
      height: 50px;
      left: 0;
      right: 0;
      bottom: 0;
      background: rgba(255, 0, 0, 0.7);
    }
    

    DEMO to try on phone

    In portrait mode it is always visible:

    portrait-mode

    In landscape mode you can scroll it off screen for the size of top address bar:

    enter image description here

    Has anyone come across such issue? I would appreciate any help to make footer stay on the screen. Thanks