iOS浏览器内核导致 fixed 定位元素可能错位问题
原文链接 http://judes.me/frontend/2016/10/11/fixed-pos-problem-in-ios-wechat-browser.html
注:以下为加速网络访问所做的原文缓存,经过重新格式化,可能存在格式方面的问题,或偶有遗漏信息,请以原文为准。
在企业号某个列表页面使用 position: fixed;
置顶搜索输入框时,发现一个诡异的问题:在 iOS 的微信浏览器中点击输入框,弹出输入法时,很有可能会(复现条件:列表长度超过一屏,在点击输入框前往下拖动列表)导致输入框错位下移,在 Android 微信浏览器中却没有问题。
在 iOS 输入法未弹出时显示正常 在 iOS 输入法弹出后出现错位
出问题的页面结构大致如下,完整的代码见这里:
<div class="container">
<div class="fixed_part">
<input type="text" placeholder="输入文字">
</div>
<div class="overflow_part">
<!--items-->
</div>
</div>
相应的样式如下:
.container {
position: relative;
}
.fixed_part {
position: fixed;
top: 0;
width: 100%;
}
.fixed_part > input {
width: 100%;
padding: 5%;
border: none;
border-bottom: 1px solid #eee;
}
.overflow_part .item {
height: 100px;
line-height: 100px;
text-align: center;
border-bottom: 1px solid #eee;
}
最初遇到这个问题时,当作没看见(一,这是兼容性问题,手尾长;二,复现条件比较苛刻;三,产品经理没发现;四,手头上事情很多;五,不想做的理由总是很多),这事就过去了。
后来又再次遇到,一时兴起想解决它。很快找到原因( iOS 原生浏览器内核对 fixed 定位元素渲染有 bug ),还看到有文章给出了解决方案。借鉴文中的思路——放弃使用 fixed 定位,同时缩窄滚动区域——给出了自己的解决方案,完整的代码见这里。
页面结构没有改变。
样式有大改变:
.container {
/* 让容器计算出自身高度 */
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
/* 让子元素处理自身高度 */
display: flex;
}
.fixed_part {
/* 用 absolute 代替 fixed */
position: absolute;
top: 0;
width: 100%;
}
.fixed_part > input {
box-sizing: border-box;
width: 100%;
padding: 5%;
border: none;
border-bottom: 1px solid #eee;
}
.overflow_part {
width: 100%;
/* 让滚动条出现在高度超过一屏的元素上面 */
overflow-y: auto;
}
.overflow_part .item {
height: 100px;
line-height: 100px;
text-align: center;
border-bottom: 1px solid #eee;
}
这个方案的好处是不需要写死——你要这样做也是可以的——任何一个元素的高度。
完成后的效果图:
在 iOS 输入法未弹出时显示正常 在 iOS 输入法弹出后显示正常