我最近听了JEN Simmons在 Boagworld播客的关于CSS Shapes的采访,虽然我之前已经听说过CSS Shapes好久了,但是我还没有亲自尝试过。因为某些原因,这个采访强迫我坐下来好好看一下CSS Shapes的出色之处(好吧,很大一部分原因是我认为Jen Simmons太帅了,我已经收听她的The Web Ahead一年多了,真的太精彩了)。
我做的第一件事就是阅读W3C规范中的CSS Shapes module level 1。是的,这份规范开始的时候读起来确实很像官方正式文件,但是有趣的地方从第二节开始,全是非常酷的东西。概括说,CSS Shapes允许我们让文字包围图形而不是仅仅在矩形的框中,现在文字可以环绕圆形、椭圆、多边形甚至一幅图片了。
在CSS Shapes出现之前,我们或多或少的受困于矩形行列的标准布局。我们可能不得不向来自打印设计的设计者解释一下:不,我们不能让文本环绕在你裁切完美的碧昂斯的照片周围。
你想要这样:
对不起,你得到的是这样:
CSS Shapes开始由Adobe Web Platform team开发,在他们的博客中从2012年开始就有关于CSS Shapes规范开发的内容。看看他们为了展示CSS Shapes的能力而创建的爱丽丝梦游仙境的酷炫的demo。重点就是用CSS Shape你完全可以让文本环绕在碧昂斯的胳膊周围。
实话说,W3C规范并不是很好理解,因此下面我试着用自己的话解释一下。给一个元素应用CSS Shape的先决条件就是这个元素要是浮动的,对于不是float的元素是没有效果的。
如果你的浏览器很好的支持CSS Shape,你应该能看到这段文本很好的环绕在碧昂斯图片的旁边,否则的话你就只会得到一个矩形行列的文本了(提示:使用Chrome或Safari浏览器)
一共有四个基本的图形函数你可以用来声明一个元素的形状,换句话说,就是你想要你的文字如何环绕你的元素。另外,你也可以从一幅图片中用α通道(alpha channel)抽取形状。
浏览器用shape-image-threshold属性来识别所需的形状,α值比阀值高的像素点构成了形状,阀值的取值是在0.0(透明)和1.0(不透明)之间。如果因为某些原因你的图片没有加载出来,就没有什么Shape可言了。
在此之前,文本只能放在浮动元素的相反的一侧,这意味着如果元素向左侧浮动,文本会涌向右侧,反之亦然。在未来,使用叫做CSS exclusions的东西将有可能让文本整个的包围着元素。
下面有个例子使用shape-outside属性来让文本跟随形状变化。
.shape {
shape-outside: url("path/to/nicely-cropped-image.png");
shape-image-threshold: 0.5;
shape-margin: 10px;
float: left;
}
共有两组Shape属性
shape-outside 让文本围在图形外,和shape-margin属性一起使用
shape-inside把文本包装在形状的内部,和shape-padding一起使用(这个属性将会推迟到CSS Shapes module level 2)
圆形:circle()函数
.circle {
/* general styles for the div*/
width: 200px;
height: 200px;
background-color: #A4F4B0;
border-radius: 50%;
/* make it a shape!*/
shape-outside: circle();
float: left;
}
用circle()函数的语法格式是:
circle([]?[at ]?)
问号表示参数是可选的。
CSS Shapes存在于一个基于坐标系的盒子参考模型。它符合CSS盒子模型,Razvan Caliman,为CSS Shapes工作的一位工程师,曾经写过一篇关于CSS盒子参考模型的很有深度的文章。
shape-radius是圆的半径,可以用任意长度单位(px,em,rem等等)或百分比表示。也可以用closest-side和farthest-side两个关键词。
closest-side使用从形状的中心到盒子参考模型的最近的边缘的距离作为半径,相反的,farthest-side使用到最远的边缘的距离。shape-radius如果为空默认值使用closest-side。
psition用这个元素坐标系中的一对x,y坐标值来表示,默认是50% 50%,在元素中心。
译者:原文中默认是0 0,在元素中心,经实验,0 0在坐标系左上角,默认是中心50% 50%。
CSS Shapes 属性即使在有人使用不支持的浏览器访问时也不会完全破坏你的布局,仅仅是退回到大部分人习惯了的普通的矩形行列的文本而已。
椭圆:ellipse()函数
.ellipse {
width: 100px;
height: 200px;
background-color: #A4F4B0;
border-radius: 50%;
shape-outside: ellipse();
float: left;
}
椭圆就像是一个圆坐下或者被压扁了而已。因此ellipse()函数的正式语法是:
ellipse( [{2}]? [at ]? )
注意在shape-radius后面的2,这意味着这个函数需要2个变量,一个是椭圆的X轴上的半径,一个是Y轴上的半径,像圆一样,默认值是closest-side。位置变量也系那个circle()函数中一样。
矩形:inset()函数
.inset {
width: 200px;
height: 160px;
background-color: #A4F4B0;
border-radius: 50px;
shape-outside: inset(0px round 50px);
float: left;
}
我花了好多时间研究inset()函数,最后还是Codepen上的代码帮了我。这是inset()函数的正式的语法:
inset( {1,4} [round ]? )
shape-arg接受变量值,按照我们给margin或者padding的缩写的方式,以上、右、下、左的顺序,我们可以传入1个、2个或四个值。inset被应用到从元素边缘到中心。
译者:这个原文说的很含糊,参考其他资料可知,这个参数的作用是指定矩形到元素四个边缘的偏移。
border-radius参数是可选的,它允许你创建圆角的矩形,让你的文本环绕在圆角周围。个人觉得,border-radius属性是使得inset()函数变得有用,因为我们之前已经可以让文本环绕在普通的矩形周围了。
译者:直接在元素上应用border-radius产生的圆角效果只是使元素边框和背景变成圆角矩形,并不能让文字按圆角浮动
多边形:plygon()函数
.polygon {
width: 200px;
height: 200px;
clip-path: polygon(0 0, 0 200px, 200px 100px);
background-color: #A4F4B0;
shape-outside: polygon(0 0, 0 200px, 200px 100px);
float:left;
}
polygon()函数允许你通过使用坐标值对作为参数来声明自定的形状,正式的语法是:
polygon( [,]? []# )
他有一个可选的属性rill-rule能够决定这个图形如何展示,特别是当你有一个复杂的形状的有许多点互相交叉的时候,默认值是nonzero.你可以从这里查阅更多关于fill-rule的信息。
每对坐标都是你期望的形状的顶点,至少有三个点才有效。在我的示例代码中,我使用clip-path裁掉元素在多边形外的一部分来创建一个多边形,所有你可以看到文本很好的环绕在周围。
创建我例子中的像三角形这样的标准形状是非常简单的,但对于许多复杂的图形,定位顶点是一件非常痛苦的事,这就是为什么Razvan Caliman发布了CSS Shapes Editor for Chrome插件,它在Chrome的elements元素查看面板增加了一个叫做Shapes的标签,它允许你在浏览器中在图形上拖拽点来调整Shapes形状。这篇文章已经很好的讲解了你如何安装和使用这个扩展程序了。
CSS Shapes的浏览器支持
CSS Shapes在Chrome 第37版中可用了,Safari自从7.1也提供了支持。这有一张本文写作时的CSS Shapes浏览器支持情况图:
不幸的是火狐和IE浏览器现在都不能支持CSS Shapes。但是这是一个值得我们关注的特性,我们自己需要去学习和准备,因为这个有可能完全改变我们的网页设计。
关于CSS Shapes的推荐阅读:
好读书不求甚解,好观察不多言语,好实践不多吹嘘;代码一团糟,混沌一学渣,前途两眼瞎。J有事请烧tzp_1991@qq.com