21

描述

此bug出现需要条件:父元素需使用绝对定位absolute或固定定位fixed,使用overflow: scroll / auto(或overflow-y: scroll / auto),内部子元素是动态大小(例如较大的svg document,近似为内嵌iframe,等等)。

bug出现原因:没有相关官方文档描述该bug。在查阅文档及自己测试的时候总结:iOS safari 会将overflow:scroll的元素识别为一个单独的 ScrollView,并予以一个 -webkit-overflow-scrolling 属性为auto。而safari中的网页本身就是一个大的ScrollView,在脱离文档流的定位时,子元素的高度如果没有在ScrollView建立之前确定,就不会触发内部滑动,而会触发外部滑动。

关于 -webkit-overflow-scrolling:Safari CSS Reference官方是这样描述的:

Specifies whether to use native-style scrolling in an overflow:scroll element.

即该属性会让overflow:scroll的元素拥有像iOS原生一样顺滑的滑动效果。为了实现此目标,safari将所有overflow:scroll的元素用原生创建一个ScrollView,当-webkit-overflow-scrolling属性为touch时,启用硬件加速,出现顺滑效果。

分析

  1. 父元素不脱离文档流时,无此bug。
  2. 父元素在不指定 -webkit-overflow-scrolling:touch时必定出现无法滑动的问题。
  3. 当内部元素为正常的html元素时,无此bug。
  4. 当为父元素重新设置overflow属性时,可能会导致safari重建ScrollView而bug消失。(之前版本的实验室用这种方法解决的,但新海外版不能用这种方法fix,所以是可能)

解决方法:

据以上分析以及大量测试得出完美解决方法为:

  1. 必须为所有在移动端的overflow: scroll元素增加属性 -webkit-overflow-scrolling: touch。
  2. 当父元素可不脱离文档流时不要脱离文档流。
  3. 在子元素iframe加载完成后可异步将父元素的overflow: scroll属性重写(此方法可能不成功)。
  4. 如以上没有解决,则给予子元素一个min-height,大小不限(略大于效果最好),帮助safari建立ScrollView(亲测最有效)。

更新

此问题的深层原因找到了,详情请见:iOS safari浏览器上overflow: scroll元素无法滚动bug深究


如果觉得我的文章对你有用,请随意赞赏

你可能感兴趣的

qzuser · 2018年03月03日

非常感谢,垃圾苹果

+2 回复

小白 · 2018年01月09日

厉害,不过现在基本都是直接用插件吧

回复

0

直接用css transform模拟的scroll插件吗?

Kinice 作者 · 2018年01月09日
0

我看大神们用的最多就是这个better-scroll,如果不需要加载功能直接实例就可以用了,基本是兼容的

小白 · 2018年01月09日
0

如果不想引入第三方库,就需要解决bug,不在乎的话这个better-scroll确实是个好选择~

Kinice 作者 · 2018年01月10日
夢の軌迹 · 1月4日

ios 微信浏览器无法解决

回复

张越 · 1月16日

谢谢楼主,我前端工作一年多全是to B的业务,这次搞 to C的小程序很多兼容性的bug,确实很棘手

回复

载入中...