最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

html - Weird CSS z-Index behavior on iOS browsers - Stack Overflow

programmeradmin1浏览0评论

Problem

I'm trying to replicate the iOS behavior of native apps, where a search box remains in view (merges with top bar) after the user has scrolled. The header is fixed and only the main content is scrollable. The search box has position: sticky and I gave it a high z-index. This works fine on Chrome/Safari desktop, but fails on iOS browsers. See behavior in action below (simplified version of my current implementation)

Scrolling on Desktop -- Works Fine

Scrolling on iOS -- Does NOT work

What I tried

  1. Using translate3d hack
 transform: translate3d(0, 0, 0);
  -webkit-transform: translate3d(0, 0, 0);
  1. Using a pseudo-element on the header with background/filter applied to it

-- No apparent change and none of this make it work on iOS.

Code Snippet (try on iOS to see the issue)

body {
  margin: 0;
  padding: 0;
  height: 100vh;
  overflow: hidden;
}

header {
  padding: 0 20px;
  height: 60px;
  position: relative;
  top: 0;
  width: 100%;
  z-index: 50;
  color: black;
  font-size: 24px;
  font-weight: bold;
  background: rgba(255, 255, 255, 0.8);
  backdrop-filter: blur(10px);
}

/* Doesn't work on iOS neither */
/* header:before {
  content: "";
  background: rgba(255, 255, 255, 0.8);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  width: 100%;
  height: 100%;
  position: absolute;
  top:0;
  left:0;
  z-index:-1;
} */

main {
  height: 100%;
}

.ios-scroll-view {
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-y: contain;
  height: 100%;
  width: 100%;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  padding-top: calc(44px + env(safe-area-inset-top, 0px));
  padding-bottom: calc(54px + env(safe-area-inset-bottom, 0px));
  background: lightgreen;
  padding-left: 16px;
}

#search {
  width: 20%;
  position: sticky;
  top: -10px;
  z-index: 999 !important;
  transform: translate3d(0, 0, 0);
  -webkit-transform: translate3d(0, 0, 0);
}
<html>

<body>
  <header>
    Title
  </header>
  <main>
    <div class="ios-scroll-view">
      <h1>Title</h1>
      <input id="search" placeholder="Search" />
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>LAST</p>
    </div>
  </main>
</body>

</html>

Problem

I'm trying to replicate the iOS behavior of native apps, where a search box remains in view (merges with top bar) after the user has scrolled. The header is fixed and only the main content is scrollable. The search box has position: sticky and I gave it a high z-index. This works fine on Chrome/Safari desktop, but fails on iOS browsers. See behavior in action below (simplified version of my current implementation)

Scrolling on Desktop -- Works Fine

Scrolling on iOS -- Does NOT work

What I tried

  1. Using translate3d hack
 transform: translate3d(0, 0, 0);
  -webkit-transform: translate3d(0, 0, 0);
  1. Using a pseudo-element on the header with background/filter applied to it

-- No apparent change and none of this make it work on iOS.

Code Snippet (try on iOS to see the issue)

body {
  margin: 0;
  padding: 0;
  height: 100vh;
  overflow: hidden;
}

header {
  padding: 0 20px;
  height: 60px;
  position: relative;
  top: 0;
  width: 100%;
  z-index: 50;
  color: black;
  font-size: 24px;
  font-weight: bold;
  background: rgba(255, 255, 255, 0.8);
  backdrop-filter: blur(10px);
}

/* Doesn't work on iOS neither */
/* header:before {
  content: "";
  background: rgba(255, 255, 255, 0.8);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  width: 100%;
  height: 100%;
  position: absolute;
  top:0;
  left:0;
  z-index:-1;
} */

main {
  height: 100%;
}

.ios-scroll-view {
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-y: contain;
  height: 100%;
  width: 100%;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  padding-top: calc(44px + env(safe-area-inset-top, 0px));
  padding-bottom: calc(54px + env(safe-area-inset-bottom, 0px));
  background: lightgreen;
  padding-left: 16px;
}

#search {
  width: 20%;
  position: sticky;
  top: -10px;
  z-index: 999 !important;
  transform: translate3d(0, 0, 0);
  -webkit-transform: translate3d(0, 0, 0);
}
<html>

<body>
  <header>
    Title
  </header>
  <main>
    <div class="ios-scroll-view">
      <h1>Title</h1>
      <input id="search" placeholder="Search" />
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>Content here...</p>
      <p>LAST</p>
    </div>
  </main>
</body>

</html>

Share Improve this question asked Mar 12 at 14:19 BassemBassem 4,0704 gold badges25 silver badges53 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

The -webkit-overflow-scrolling was causing the issue, setting it to auto solves the problem.

-webkit-overflow-scrolling: auto
发布评论

评论列表(0)

  1. 暂无评论