ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
&emsp;&emsp;CSS规范新增了一个模块:CSS Shapes,shape-outside属性属于该模块,它能影响浮动元素周边内容流的形状(即浮动形状),可接收三类值:形状盒子、函数和图像。 ## 一、形状盒子 &emsp;&emsp;形状盒子(shape box)会指定形状的边界,既能单独使用,也能与另外两类值组合使用,可选的关键字如下所列,其中margin-box是shape-outside属性的默认值。 &emsp;&emsp;(1)margin-box:以外边距为界。 &emsp;&emsp;(2)border-box:以边框为界。 &emsp;&emsp;(3)padding-box:以内边距为界。 &emsp;&emsp;(4)content-box:以内容为界。 &emsp;&emsp;下图演示了四种形状盒子的效果,外边距、边框和内边距都设为了10px,代码中只列出了关键样式,并只举了其中的一种情况。 ~~~html <style> .container { overflow: hidden; } div { float: left; padding: 10px; margin: 10px; border: 10px solid #FC0; background: #F60; background-clip: content-box; } .border-box { shape-outside: border-box; } </style> <section class="container"> <div class="border-box">border-box</div> <p>My name is Strick.</p> <p>My name is Strick.</p> <p>My name is Strick.</p> <p>My name is Strick.</p> <p>My name is Strick.</p> </section> ~~~ :-: ![](https://img.kancloud.cn/ba/6a/ba6af0b12c9a2f357309720669222252_1280x477.png) ## 二、函数 &emsp;&emsp;有4个形状函数可供选择,分别是circle()、ellipse()、inset()以及polygon()。 **1)circle()** &emsp;&emsp;第一种是圆形,可定义半径和圆点位置,例如浮动元素的宽高都为100px,圆的半径为50px,样式如下所示,效果如下图所示,其中白色边框的圆就是计算出的浮动形状。 ~~~css div { float: left; width: 100px; height: 100px; shape-outside: circle(50px); } ~~~ :-: ![](https://img.kancloud.cn/73/cf/73cf336df4d8909a04a2566223a6dbbb_611x304.png) &emsp;&emsp;接下来指定圆点的位置,需要使用at关键字将半径和位置分隔。在下面的样式中,圆点处在元素的右上角,注意观察下图中的浮动形状,它超出了元素的边界,超出部分默认会被裁剪掉。 ~~~CSS div { shape-outside: circle(50px at right top); } ~~~ :-: ![](https://img.kancloud.cn/39/00/3900364a28630534e42f9f6783d72b27_610x304.png) &emsp;&emsp;当用百分数指定半径时,需要有个参照值,该值得通过下面的公式计算得到,其中width是形状盒子的宽,height是其高。 :-: ![](https://img.kancloud.cn/11/63/1163e408d05760e97d3ca12187199422_628x73.png) &emsp;&emsp;假设半径为10%,浮动元素的上下外边距为10px,因为默认是以外边距为界限,所以此处形状盒子的高度为120px,宽度仍然是100px,那么通过计算后得到的参照值约等于110px,半径就是11px,效果如下图所示。 ~~~CSS div { margin: 10px 0; shape-outside: circle(10%); } ~~~ :-: ![](https://img.kancloud.cn/2c/52/2c5259a0d8b471adf7396170c1fa27ce_610x304.png) **2)ellipse()** &emsp;&emsp;第二种是椭圆,与圆形类似,也需要定义半径和圆点位置。只是它需要两个半径,第一个是横轴半径,第二个是纵轴半径。在下面的示例中,浮动元素的宽为100px,高为60px,将浮动形状声明为椭圆,效果如下图所示。 ~~~CSS div { float: left; width: 100px; height: 60px; shape-outside: ellipse(50px 30px); } ~~~ :-: ![](https://img.kancloud.cn/b3/0e/b30ee84a84a19673dc389459bcb80e39_610x219.png) &emsp;&emsp;横轴上的百分数半径参照形状盒子的宽度,纵轴上的百分数半径参照形状盒子的高度,下面定义的百分数半径经过计算后得到的值为50px和40px,效果如下图所示。 ~~~CSS div { margin: 10px 0; shape-outside: ellipse(50% 50%); } ~~~ :-: ![](https://img.kancloud.cn/dc/ec/dcec54567369ff771111236578488027_610x219.png) **3)inset()** &emsp;&emsp;第三种是嵌入在形状盒子中的内部矩形,它能接收一组值,分别表示上右下左向内偏移的距离,还能接收一个可选的圆角,以round关键字分隔。 &emsp;&emsp;在下面的示例中,虽然只提供了两个值,但CSS会根据现有的值确定其余值,内部矩形距离形状盒子的顶端和底端是20px,左右边界是10px,形状盒子的宽为100px,高为80px,效果如下图所示。 ~~~CSS div { float: left; width: 100px; height: 60px; margin: 10px 0; shape-outside: inset(20px 10px); } ~~~ :-: ![](https://img.kancloud.cn/b5/29/b529af51e2cbed1cf7d2bf0701ecdae0_610x219.png) &emsp;&emsp;下面的样式为内部矩形添加了20px的圆角,效果如下图所示。 ~~~CSS div { shape-outside: inset(20px 10px round 20px); } ~~~ :-: ![](https://img.kancloud.cn/02/02/0202c539fc6c05afc60f4bae183d38db_610x219.png) &emsp;&emsp;当内部矩形的偏移值是百分数时,左右偏移参照的是形状盒子的宽,上下偏移参照的是其高。例如参数值为20%,那么计算出的左右偏移值是20px,上下偏移值是16px,效果如下图所示。 ~~~CSS div { shape-outside: inset(20%); } ~~~ :-: ![](https://img.kancloud.cn/5a/06/5a0634dbcfe4d1f8e05287da8c16f1fa_610x219.png) **4)polygon()** &emsp;&emsp;第四种是多边形,它能接收一系列坐标对,相对于形状盒子的左上角计算,将所有的点连接起来就是最终的形状。根据下面的polygon()函数中的四组坐标可描绘出一个直角梯形,如下图所示。 ~~~CSS div { float: left; width: 100px; height: 80px; shape-outside: polygon(10px 10px, 20px 10px, 40px 50px, 10px 50px); } ~~~ :-: ![](https://img.kancloud.cn/f1/58/f15866e0bc700b4bb02b9d424661bc4e_610x219.png) &emsp;&emsp;当坐标是百分数时,横坐标参照形状盒子的宽,纵坐标参照其高,下面定义的坐标,效果与上图一致。 ~~~CSS div { shape-outside: polygon(10% 12.5%, 20% 12.5%, 40% 62.5%, 10% 62.5%); } ~~~ &emsp;&emsp;有一种简便的方式创建多边形,那就是使用Chrome的浏览器插件:CSS Shapes Editor,用拖拽鼠标的方式得到想要的多边形,再将参数复制到样式表中,如下图所示。 :-: ![](https://img.kancloud.cn/f1/ee/f1ee699f670171b127d50d52f4ec6991_981x509.png) ## 三、图像 &emsp;&emsp;当形状很复杂时,直接画多边形会非常麻烦,不过shape-outside属性可基于图像的透明度(alpha值)来绘制形状,即形状轮廓会沿着非透明区域的边缘生成。 &emsp;&emsp;例如有一个五角星,如果边以外的地方都是透明的,那么周围的内容就会贴着五角星的边,如下图所示。 ~~~CSS div { float: left; width: 100px; height: 100px; shape-outside: url(./star.png); } ~~~ :-: ![](https://img.kancloud.cn/df/26/df265fb8ba7498a8c07a1120ae141e03_493x250.png) 注意,url()函数中的图像不能直接从本地加载,必须从Web服务器中读取,如此引用的图像会有HTTP首部信息,用于判断是否跨域。 **1)shape-image-threshold** &emsp;&emsp;该属性可指定透明度阈值,修改形状边界,其取值范围是0~1,值越小透明度越高。对于透明度低于该值的部分,会包含在浮动形状中,而高于的则不包含。 &emsp;&emsp;例如将该值设为1时,就表示没有浮动形状,即整张图像都不在浮动形状中,如下图所示。 ~~~CSS div { shape-image-threshold: 1; } ~~~ :-: ![](https://img.kancloud.cn/4a/7f/4a7f0ae5d9060dc3c70a6b76f6b161e2_493x250.png) **2)shape-margin** &emsp;&emsp;该属性可指定浮动形状的外边距。在下面的示例中会添加10px的外边距,效果如下图所示。 ~~~CSS div { shape-margin: 10px; } ~~~ :-: ![](https://img.kancloud.cn/ab/b4/abb4178f3bf12fa1d8859c9a7710be89_493x250.png) &emsp;&emsp;注意,shape-margin属性的百分数的计算方式与普通的外边距相同,参照的也是包含块的宽度。假设div元素的包含块的宽度为220px,那么10%的外边距经过计算后得到的值为22px,效果如下图所示。 ~~~CSS div { shape-margin: 10%; } ~~~ :-: ![](https://img.kancloud.cn/29/a8/29a8d4d8b7d21d2d03e1ecba26d5dbc1_493x250.png) ***** > 原文出处: [博客园-CSS躬行记](https://www.cnblogs.com/strick/category/1667864.html) [知乎专栏-CSS躬行记](https://zhuanlan.zhihu.com/pwcss) 已建立一个微信前端交流群,如要进群,请先加微信号freedom20180706或扫描下面的二维码,请求中需注明“看云加群”,在通过请求后就会把你拉进来。还搜集整理了一套[面试资料](https://github.com/pwstrick/daily),欢迎浏览。 ![](https://box.kancloud.cn/2e1f8ecf9512ecdd2fcaae8250e7d48a_430x430.jpg =200x200) 推荐一款前端监控脚本:[shin-monitor](https://github.com/pwstrick/shin-monitor),不仅能监控前端的错误、通信、打印等行为,还能计算各类性能参数,包括 FMP、LCP、FP 等。