微信小程序 fixed 定位在 scrollview 中失效

少说废话先上东西

小程序片段代码导入

在这段代码片段中创建了一个高度为300rpxscroll-view容器。并且在容器中有一个fixed定位的内容如下所示。

css
.fixed-center {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

上面这张截图是在开发者工具中展示的样子。scroll-view 正常滚动,fixed定位的内容在屏幕的正中间,这符合我们的预期。

但是当我们用真机去预览的时候发现原本应该fixed在中间的内容不展示了。WTF!!!

为什么???

-webkit-overflow-scrolling: touch

没错万恶之源就是这个css属性:-webkit-overflow-scrolling: touch MDN 介绍

没想到吧 MDN 警告不要在生产环境使用,但是微信小程序就是加了这个属性在scroll-view上。那就让我们来找找这个属性。

  1. 调试微信开发者工具
  1. 找到模拟器对应的 webview
  1. 调试 webview

通过在 devtool 中输入以下代码,来打开对应 webview 的 devtool

TIP

你的 webview 可能不是下标为 [1] 哦~

javascript
document.getElementsByTagName('webview')[1].showDevTools(true)
  1. 审查元素
css
.wx-scroll-view {
  -webkit-overflow-scrolling: touch;
  height: 100%;
  max-height: inherit;
  position: relative;
  width: 100%;
}

我们会找到上面这样的一段 css 样式。

这个属性影响了什么?

小程序官方说明

网上说 Safari 对于overflow-scrolling用了原生控件来实现。对于有-webkit-overflow-scrolling的网页,会创建一个 UIScrollView,提供子 layer 给渲染模块使用。

解决方案

  1. 把 fixed 元素放到 scroll-view 外面

  2. 覆盖-webkit-overflow-scrolling: touch, 把值改成 auto

  3. 弃用 scroll-view,使用 view 配合 overflow-y: auto 来达成滚动效果

第 2 点覆盖 css 代码如下

css
.wx-scroll-view {
  -webkit-overflow-scrolling: auto;
}

结尾

2022,是时候告别-webkit-overflow-scrolling 了,因为在 iOS 13 之后,不需要再设置-webkit-overflow-scrolling

了,所有可滚动的框架,或者设置 overflow 滚动的元素默认都是弹性效果了。也不知道小程序什么时候会去掉:P。