【问题标题】:iOS not respecting z-index with -webkit-overflow-scrollingiOS 不尊重 z-index 与 -webkit-overflow-scrolling
【发布时间】:2016-10-08 09:10:12
【问题描述】:

问题:

在 iOS 上,使用 -webkit-overflow-scrolling 时,可滚动区域的 z-index 会被忽略。如果两个带有-webkit-overflow-scrolling 的对象重叠,则滚动下方的对象,而不是上方显示的对象。

如何重现:

创建两个相互重叠的元素(例如position: absolute),其中一个具有更高的z-index 并添加

.selector
{
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}

他们俩。两个元素都应该有足够的内容可以滚动。

额外添加

<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="apple-mobile-web-app-capable" content="yes"> 
<meta name="apple-mobile-web-app-status-bar-style" content="black">

到您的&lt;head&gt;。然后将该页面添加到您的主屏幕并从那里启动它。

如果您随后尝试滚动上方的元素,则会滚动下方的元素。

MCVE:

或者,只需查看 this pen。从您的 iOS 设备启动 full 版本,将其添加到您的主屏幕并从那里启动。

环境:

在带有 iOS 9.1iOS 9.3.2

iPhone 5iPhone 6 上测试

观察:

  • 该问题仅在从主屏幕(固定应用)或 Xamarin Webview(可能与 UIWebView 和 WKWebView 有关)启动页面/应用时出现
  • 在页面加载后更改设备方向(纵向/横向)后,问题得到修复,直到页面重新加载(也许重新触发布局已修复?)
  • 通过 JS 将下部元素 overflow-y 更改为 hidden 确实可以解决问题,但是切换 overflow 会导致重绘导致性能问题
  • html, body 中删除 height: 100%; width: 100% 也可以解决问题,但是必须设置这些百分比值才能正常工作

需要一个适当的解决方案/解决方法来解决此问题,而不会造成任何麻烦的副作用。也将不胜感激解释为什么会发生这种情况。

【问题讨论】:

  • 如果元素应用了 3d 变换,我也遇到过类似的 z-index 错误。目前我没有 iOS 设备来测试这个,但你可以尝试删除 3d 变换。
  • 你的问题到底是什么?据我所知,iOS 上的 z-index 存在两个问题。一种是 z-index 元素以错误的顺序显示,另一种是上面描述的滚动错误的项目。

标签: html ios css scroll z-index


【解决方案1】:

本质上,您遇到的是-webkit-overflow-scrolling: touch; 的 iOS 错误。为了解决这个bug,按照this answer,只需将以下CSS样式添加到可滚动的div

-webkit-transform: translateZ(0px);
-webkit-transform: translate3d(0,0,0);
-webkit-perspective: 1000;

总而言之,如果您将上述样式添加到 CSS 中 scrollable 类的样式中,它应该可以工作。在运行 iOS 9 的 iPhone 5s 上进行了测试。请注意,如果您向下滚动到高于其他所有内容的可滚动部分的底部或顶部,它将开始滚动正文。

我相信这些额外样式的作用是诱使 iPhone 使用 GPU,但请记住,它们只是因为 Safari 的错误才需要 - 这不是你的错,这些额外的样式不应该真的需要包括。但是将它们放入您的 CSS 中,它应该会像做梦一样工作!

【讨论】:

  • 我需要为列表中不可见的项目添加 0 个转换。但这仍然帮助我到达那里。荣誉
  • 除此之外,在我的情况下,重叠元素需要transform: translateZ(...px),其值高于滚动元素(下方的那个)。否则,当滚动元素离开屏幕(我也有水平滚动)并且发生重绘时,它会再次出现在顶部,这是错误的。这个答案让我到了那里,谢谢!
【解决方案2】:

一个非常简单的解决方法是在滚动时将一个类切换到正文并定位您的可滚动窗口。如果您正在滚动 .scrollA,则将类 scrollB 切换到 body 并应用类似 Javascript/css 的内容,或者您​​可以使用 javascript 完成所有操作,您可以选择。

Javascript

$('#targetDivA').on('scroll touch', function(){
   $('body').toggleClass('scrollB);

   //or use this to navigate to it
   //$(this).siblings().toggleClass(\'scrollB\')
})

CSS

body.scrollB .targetDivB {
    pointer-events: none;
    /*this eliminates the device from using any event until removed*/
}

希望这可以帮助你交配!

【讨论】:

    【解决方案3】:

    【讨论】:

      【解决方案4】:

      需要时动态删除此属性。它不太复杂,不会引起副作用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-21
        相关资源
        最近更新 更多