shape-outside元素实现iphone刘海效果

iphoneX的诞生,让很多人对它的刘海感到非常大的好奇心,那对于我们前端开发的人来说,关注点就是在他的布局上面了,怎么实现字体环绕他进行滚动?让文字不会被刘海挡住。效果图如下:

image

CSS3里面针对这种特定形状环绕的效果已经支持很久了,CSS3 Shapes和CSS3 Regions都是可以实现的,接下来我们就用shapes来实现这一效果。
shape-outside属性要想生效,本身需要是浮动float元素。
本文demo效果实现使用的是shape-outside:polygon(),通过点坐标勾勒出和齐刘海形状相似的多边形形状,CSS代码如下

1
2
3
4
5
6
7
.shape{
float: left;
width: 30px;
height: 340px;
shape-outside: polygon(0 0, 0 150px, 16px 154px, 30px 166px, 30px 314px, 16px 326px, 0 330px, 0 0);
transition: shape-outside .15s;
}

此时,后面没有设置BFC(块状格式化上下文)的列表元素就会自动环绕这个形状排列,也就是自动避开了齐刘海区域。
接着就是把刘海的图片覆盖在这个刘海区域上面,这样,刘海就做成了。
接着就是实现文字环绕刘海滚动的效果:
由于shape-outside所在的元素是浮动元素,因此,必定会跟着容器一起滚动,我们需要的效果是我们所绘制的这个刘海区域需要是固定的,那么我们就需要监听整个容器的滚动事件,将容器滚动的高度scrollTop加载每个刘海的纵坐标上面,具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script type="text/javascript">
var box=document.getElementById("box"); //这个是外层容器
var shape=document.getElementById("shape"); //这个是刘海容器
shape.style.height=box.scrollHeight+"px";  //这个的作用是将刘海的高度始终保持位置固定
var fn=function(){
var scrollTop=box.scrollTop; //获取容器滚动的高度
var shapeOutside = 'polygon(0 0, 0 '+ (150 + scrollTop) +'px, 16px '+ (154 + scrollTop) +'px, 30px '+ (166 + scrollTop) +'px, 30px '+ (314 + scrollTop) +'px, 16px '+ (326 + scrollTop) +'px, 0 '+ (330 + scrollTop) +'px, 0 0)'; //将纵坐标加上scrollTop就实现了刘海固定的效果
shape.style.webkitShapeOutside = shapeOutside;//兼容性
shape.style.shapeOutside=shapeOutside;//将更新后的shapeOutside始终保持更新
};
 //滚动监听
box.onscroll=function(){
fn();
}
fn();
</script>

兼容性

CSS Shapes的兼容性为Chrome浏览器和Safari浏览器(包括iOS)都是支持的,也就意味着我们是可以在iPhone上使用的,完美。只是需要注意的是在iOS10.2及其之前的版本,CSS Shapes的使用还是需要加webkit私有前缀的,但据说iPhone X至少默认iOS 11,而刘海头交互效果就是针对iPhone X处理的,因此webkit私有前缀不加也没关系。

demo

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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<!DOCTYPE html>
<html>
<head>
<title>刘海</title>
<style type="text/css">
.box{
width: 500px;
height: 450px;
margin: auto;
overflow: auto;
border:2px solid #000;
}
.shape{
float: left;
width: 30px;
height: 340px;
shape-outside: polygon(0 0, 0 150px, 16px 154px, 30px 166px, 30px 314px, 16px 326px, 0 330px, 0 0);
transition: shape-outside .15s;
}
.icon{
width: 24px;
height: 180px;
background: url(http://www.zhangxinxu.com/study/201709/liu.png) no-repeat left center;
position: absolute;
margin-top: 150px;
}
.content ul{
list-style: none;
margin: 0;
padding: 0;
}
.content li{
border-bottom: 1px solid #eee;
padding: 10px;
}
</style>
</head>
<body>
<div class="box" id="box">
<span class="shape" id="shape"></span>
<span class="icon"></span>
<div class="content">
<ul>
<li>box1</li>
<li>box1</li>
<li>box1</li>
<li>box1</li>
<li>box1</li>
<li>box1</li>
<li>box1</li>
<li>box1</li>
<li>box1</li>
<li>box1</li>
<li>box1</li>
<li>box1</li>
<li>box1</li>
<li>box1</li>
<li>box1</li>
<li>box1</li>
<li>box1</li>
<li>box1</li>
<li>box1</li>
<li>box1</li>
<li>box1</li>
<li>box1</li>
<li>box1</li>
<li>box1</li>
<li>box1</li>
<li>box1</li>
<li>box1</li>
<li>box1</li>
<li>box1</li>
<li>box1</li>
</ul>
</div>
</div>
<script type="text/javascript">
var box=document.getElementById("box");
var shape=document.getElementById("shape");
shape.style.height=box.scrollHeight+"px";
var fn=function(){
var scrollTop=box.scrollTop;
var shapeOutside = 'polygon(0 0, 0 '+ (150 + scrollTop) +'px, 16px '+ (154 + scrollTop) +'px, 30px '+ (166 + scrollTop) +'px, 30px '+ (314 + scrollTop) +'px, 16px '+ (326 + scrollTop) +'px, 0 '+ (330 + scrollTop) +'px, 0 0)';
shape.style.webkitShapeOutside = shapeOutside;
shape.style.shapeOutside=shapeOutside;
};
box.onscroll=function(){
fn();
}
fn();
</script>
</body>
</html>

这样就实现了文字环绕刘海的效果

参考网站:地址1|地址2
作 者:陈焦滨&kevin

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器