看到旭神博客上的一篇文章,关于iPhone X刘海发型设计和衍生的交互,其就是通过CSS3 Shapes实现元素滚动自动环绕iPhone X头部刘海效果。这里我整理了一下,写一个缩减版。
iPhone X的刘海发型和衍生的交互
首先先看一下微博上流传的交互样式。
可以看出此交互就是滚动页面时,列表会环绕着iPhoneX的刘海排列。
实际上,CSS3里面针对这种特定形状环绕的效果已经支持很久了,CSS3 Shapes和CSS3 Regions都是可以实现的,只是我们接触甚少。
CSS Shapes环绕iPhone X刘海简易方法
这里就描述一种在技术上简单易懂的解决方式。
实现原理
CSS Shapes中有个CSS属性名为shape-outside
,可以让内联元素以不规则的形状进行外部排列,语法如下:
/* 函数值 */
shape-outside: circle();
shape-outside: ellipse();
shape-outside: inset(10px 10px 10px 10px);
shape-outside: polygon(10px 10px, 20px 20px, 30px 30px);
/* <url>值 */
shape-outside: url(image.png);
/* 渐变值 */
shape-outside: linear-gradient(45deg, rgba(255, 255, 255, 0) 150px, red 150px);
shape-outside
属性想要生效,本身需要是浮动float
元素。
本demo效果实现的简易方法就是使用shape-outside:url('image.png')
属性实现类似效果,image.png
就是用来被环绕的图片,相当于iPhoneX的刘海设计,环绕与否是基于计算alpha通道决定,简单来讲,就是沿着图片非透明区域环绕。
由于使用url()
的形状计算是基于图片元素,和Shapes其他四个inset()
,circle()
,ellipse
和polygon()
这些基础形状方法的计算性质不一样,可以直接使用垂直方向的margin
进行偏移。
先来看下实现效果吧
细节说明
列表环绕的刘海图片和实际在页面显示的刘海图并非是一张图片,为了让刘海和列表文字之间留有空隙,要将url('liu-outside.png')
中的 liu-outside.png
图片做实色填充处理,这里是填充了6像素。
代码:
css代码
*{
margin: 0;
padding: 0;
list-style: none;
}
.box{
max-width: 600px;
height: 380px;
border: 4px solid #000;
overflow: auto;
margin: auto;
}
.liuOutside{
float: left;
width: 30px;
height: 180px;
margin-top: 100px;
-webkit-shape-outside: url('./liu-outside.png');
shape-outside: url('./liu-outside.png');
transition: margin-top .15s;
}
.liuhai{
width: 24px;
height: 180px;
background: url("./liu.png") no-repeat left center;
margin-top: 100px;
position: absolute;
}
.scrollContent li{
border-bottom: 1px solid #ddd;
padding: 1em;
}
html代码
<div class="box">
<i class="liuOutside"></i>
<i class="liuhai"></i>
<ul class="scrollContent">
<li>这个方法是比较简单的</li>
<li>使用shape-outside url(image.png)语法</li>
<li>其中'image.png'就是用来被环绕的图片</li>
<li>环绕与否是基于计算alpha通道决定</li>
<li>即沿着图片非透明区域环绕</li>
<li>为了不至于列表靠的太近</li>
<li>shape的url图片右侧</li>
<li>刻意填充了6像素实色</li>
<li>现在看到的齐刘海</li>
<li>是覆盖在上面的一张图</li>
<li>实际生效的是后面浮动的shape</li>
<li>此功能的实现需要JS的配合</li>
<li>主要控制margin-top值</li>
<li>只能对内联信息进行跟随控制</li>
</ul>
</div>
js代码
var liuOutside = document.querySelector(".liuOutside");
var box = document.querySelector(".box");
var outside = function() {
var scrollTop = box.scrollTop;
// 滚动偏移应用在margin-top上
liuOutside.style.marginTop = (100 + scrollTop) + "px";
};
// 滚动时实时监听改变shape的形状
box.addEventListener("scroll",outside);
outside();
Tips
1.效果的实现必须要js代码的配合,否则会出现很难受的效果,如下:
2.还有一种实现方案就是shape-outside:polygon()
,通过点坐标勾勒出和齐刘海形状相似的多边形形状,css代码如下:
.liuOutside{
float: left;
shape-outside: polygon(0 0, 0 100px, 16px 104px, 30px 116px, 30px 264px, 16px 276px, 0 280px, 0 0);
}
应该想到的是,既然方法换了,那么js代码相应的也需要作出改变:
box.addEventListener('scroll', function () {
var scrollTop = box.scrollTop;
// 滚动偏移应用在shape-outside上
shape.style.shapeOutside = 'polygon(0 0, 0 '+ (100 + scrollTop) +'px, 16px '+ (104 + scrollTop) +'px, 30px '+ (116 + scrollTop) +'px, 30px '+ (264 + scrollTop) +'px, 16px '+ (276 + scrollTop) +'px, 0 '+ (280 + scrollTop) +'px, 0 0)';
});
此方法在确定环绕点时比较繁琐。
3.附上用到的两张刘海图片
注:根据张鑫旭大牛的文章所写,一起学习。