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

(Safari兼容)overflow和overflow-scrolling导致fixed元素不显示

当元素同时拥有overflow:scroll和-webkit-overflow-scrolling:touch两个属性时, 可能会导致内部的fixed元素无法显示.

表现

有如下Dom结构及CSS样式
html结构:

1
2
3
<div class="wrapper">
<div class="inner"></div>
</div>

css样式:

1
2
3
4
5
6
7
8
9
10
11
12
13
.wrapper {
width: 300px;
height: 300px;
background-color: red;
}
.inner {
position: fixed;
top: 150px;
left: 150px;
width: 300px;
height: 300px;
background-color: yellow;
}

wrapper的背景色为红色.
inner是一个fixed元素, 背景色为黄色.
54279d8e.png

当给wrapper添加如下两个属性时,wrapper范围外的inner会被隐藏.

1
2
3
4
5
6
7
8
9
.wrapper {
-webkit-overflow-scrolling: touch;
overflow: scroll;
}
// or
.wrapper {
-webkit-overflow-scrolling: touch;
overflow: auto;
}

9d814290.png

解决办法

1 不要把fixed元素放在带滚动条的元素里
2 给可滚动元素的祖先元素添加translate3d, 例如:

1
2
3
body {
transform: translate3d(0, 0, 0);
}

需注意,添加translate3d的祖先元素必须位于fixed元素下

沿用上面的Dom结构,用fixFixed祖先元素包裹wrapper

1
2
3
4
5
<div class="fixFixed">
<div class="wrapper">
<div class="inner"></div>
</div>
</div>

给fixFixed添加如下样式:

1
2
3
4
.fix-fixed {
transform: translate3d(0, 0, 0);
border: 1px solid;
}

结果如下,fixFixed外的fixed元素未被显示.
3.PNG

最后用height增加fixFixed的高度,这次fixed完整显示了.

1
2
3
4
5
.fix-fixed {
transform: translate3d(0, 0, 0);
border: 1px solid;
height: 600px;
}

4.PNG

示例代码

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
<!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>overflow-scrolling与fixed</title>
<style>
html,
body {
height: 100%;
}
body {
margin: 0;
/* transform: translate3d(0, 0, 0); */
}
.fix-fixed {
transform: translate3d(0, 0, 0);
overflow: hidden;
border: 1px solid;
height: 500px;
}

.wrapper {
position: relative;
-webkit-overflow-scrolling: touch;
overflow: scroll;
overflow: hidden;
width: 300px;
height: 300px;
background-color: red;
}
.inner {
position: fixed;
top: 150px;
left: 150px;
width: 300px;
height: 300px;
background-color: yellow;
opacity: 0.8;
}
</style>
</head>
<body>
<div class="fix-fixed">
<div class="wrapper">
<div class="inner"></div>
</div>
</div>
</body>
</html>