1. 表现
  2. 解决办法
  3. 完整的示例代码

(Ios夸克浏览器兼容)可滚动元素内的fixed元素无法固定

表现

可滚动(oveflow:scroll)元素滚动时, 其内的固定定位(position: fixed)元素无法保持在原有位置,直到滚动结束才能恢复.
该bug仅能在ios上的夸克中触发,android则无此问题.

有如下Dom结构及样式:

1
2
3
4
5
<body>
<div class="outer">
<div class="header">header</div>
</div>
</body>
1
2
3
4
5
6
7
8
9
10
.outer {
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
.header {
position: fixed;
top: 0;
width: 100%;
height: 60px;
}

outer是可滚动元素,其内的header是固定定位元素.
当outer滚动时,可以观察到header的位置发生了变化,无法继续固定在顶部.

ezgif.com-optimize.gif

解决办法

不要把固定定位元素放在可滚动元素内.
这似乎是唯一可用的解决方式,目前没有找到其他可行的办法.

沿用上面的例子,把header元素移动到outer元素外,修改后的Dom结构为:

1
2
3
4
<body>
<div class="outer"></div>
<div class="header">header</div>
</body>

完整的示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>fix fixed</title>
<style>
html {
height: 100%;
overflow: hidden;
}

body {
height: 100%;
overflow: hidden;
margin: 0;
}

.outer {
text-align: center;
position: absolute;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
top: 0;
left: 0;
right: 0;
bottom: -1px;
background: red;
}

.header {
text-align: center;
position: fixed;
top: 0;
width: 100%;
height: 60px;
line-height: 60px;
background: rgba(255, 255, 255, 0.8);
}
</style>
</head>

<body>
<div class="outer">
<div class="header">header</div>
<div class="inner"></div>
</div>

<script>
const innerEl = document.querySelector('.inner')
let counter = 0
while (counter < 100) {
const el = document.createElement('div')
el.innerText = counter
innerEl.appendChild(el)
counter++
}
</script>
</body>

</html>