Skip to content

Instantly share code, notes, and snippets.

@nicolaskopp
Last active April 4, 2024 04:30
Show Gist options
  • Star 25 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save nicolaskopp/637aa4e20c66fe41a6ea2a0773935f6e to your computer and use it in GitHub Desktop.
Save nicolaskopp/637aa4e20c66fe41a6ea2a0773935f6e to your computer and use it in GitHub Desktop.
Fix scrolling bug on iOS Safari with fixed elements and bottom bar
/* Fix scrolling bug on iOS Safari with fixed elements and bottom bar */
body.noscroll {
height: 100%;
overflow: hidden; /* make sure iOS does not try to scroll the body first */
}
/* your wrapper, most likely mobile menu */
.fixed-wrapper {
width: 100%;
position: fixed;
top: 0px; /* adding px unit also seems to be important for whatever reason, albeit I think we all concur that this should be unitless */
left: 0px;
bottom: 0px;
height: 100vh;
overflow: scroll; /* not auto! */
/* magic mobile viewport iOS bug fix */
/* also see: https://css-tricks.com/css-fix-for-100vh-in-mobile-webkit/ */
/* also see: https://allthingssmitty.com/2020/05/11/css-fix-for-100vh-in-mobile-webkit/ */
height: -webkit-fill-available;
-webkit-overflow-scrolling: touch;
}
/* your actual content, which is higher than the outer element */
.fixed-wrapper .fixed-content {
min-height: 100vh; /* this is the magic, actually bug abusing iOS here */
}
@steida
Copy link

steida commented Jan 1, 2023

@Offirmo
Copy link

Offirmo commented Nov 1, 2023

Hi from 2023!

@steida Yes, using lvw, lvh is the fix at the moment

HOWEVER there is another bug:

  • when pinned on iPhone (PWA / "pin to home screen")
  • when requesting fullscreen (meta viewport-fit=cover, webmanifest "display": "fullscreen")

body's position must NOT be "fixed", or it strangely crops to the small viewport! (seen 2023/11 iOs 16.6.1 iPhone 14) (strangely it works with position: absolute but that's not the same)

The solution is

  • ensure root element (:root, html) has no padding, no margin, no border
  • ensure body has height 100 lvh
/* apply a natural box layout model to all elements
 * https://www.paulirish.com/2012/box-sizing-border-box-ftw/
 */
:root                  { box-sizing: border-box; }
*, *::before, *::after { box-sizing: inherit; }

:root, body {
  margin: 0;
  padding: 0;
  border: initial;
}

body {
  overflow: hidden;
  width: 100lvw;
  height: 100lvh;
}

@zigavidmar
Copy link

If you are still experiencing this issue and the above hasn't helped check if you have a "position: relative" on the body or html tag and remove it. This was the issue scrolling was broken on safari mobile for me.

@luishdez
Copy link

luishdez commented Feb 7, 2024

@zigavidmar yes! it's happening to me as well. And apparently it gets worse with multiple relative parents or horizontal scrolling.

I tried with an empty page and it was fine ( not feeling native.. ) , once you add more depth it gets worse. And the elastic control that allows you to move to another tabs etc makes a lot of conflicts.

BTW: little bit of topic but related. Framer motion has same problem with child animations that mix px and % or relative units. Animations doesn't work , but they work fine after the dragStart event it's triggered. The webkit renders properly.

I forgot. There is another actor in the issue. The touch algo. That analyze and predicts your intent. A huge scroll area usually works fine...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment