basic-shape 数据类型
前言
<basic-shape>是一种特殊的CSS数据类型,用于表示使用基本形状函数,从而应用相应的形状或路径;目前支持<basic-shape>类型的属性有:
shape-outside:该属性用于指定周围内联元素环绕时所包围的形状;clip-path:该属性用于指定所属盒模型的裁剪形状;offset-path:该属性用于指定元素移动的路径,属于offset属性中的一个;
形状函数
关于参考盒模型
由于形状作用的盒模型根据具体的CSS属性有所不同,它可以是margin-box、padding-box、border-box和content-box中的任何一个,因此用参考盒模型来指代这个具体的盒模型;
When using this syntax to define shapes, the reference box is defined by each property that uses
values. [1] 
inset
inset函数定义了一个矩形形状,只不过这个矩形是由参考盒模型四个边框向内形成的内嵌矩形;语法如下:
inset( <length-percentage>{1,4} [ round <‘border-radius’> ]? )[2]
可以看出参数分为两个部分,前面是1-4个长度/百分比参数,用于设置矩形距离参考盒模型相应方向的边框距离;
- 1个值:所有方向的距离一致,百分比为对应方向上盒模型的长度;
 - 2个值:第一个值代表上和下方向,第二个值代表左和右方向;
 - 4个值:依次为上、右、下和左,顺时针方向;
 
后面一组是可选参数,为round关键字加上border-radius的语法,用于设置内嵌矩阵的圆角效果;如:
1  | .demo {  | 
circle
顾名思义,circle函数就是用于指定一个圆形形状,语法如下:
circle( <shape-radius>? [ at <position> ]? )[3]
参数依然是两个部分,第一个参数为半径,是可选的,默认值W3C文档上没有说明,但是据观察为盒模型的最短边的一半(注意:这可与50%的效果是不一样的!);当使用百分比时,长度的参照值为:
这里的宽度和高度指的都是参考盒模型;后面一个参数也是可选的,为at关键字加上一组坐标位置,用于指定圆心坐标,坐标默认值为center;
ellipse
ellipse函数则是指定一个椭圆形状,语法如下:
ellipse( [ <shape-radius>{2} ]? [ at <position> ]? )[4]
同样,这里参数也是两个部分,都是可选的;第一部分为半径,两个参数(注意:这里要么完全省略,要么只能两个参数都写,一个参数是非法的!),第一个参数为x方向半径,第二个参数为y方向半径,默认值为50% 50%;第二部分与circle函数类似,用于指定椭圆中心位置,默认值为center;
polygon
polygon函数则是用来绘制任意多边形状的,语法如下:
polygon( <‘fill-rule’>? , [<length-percentage> <length-percentage>]# )[5]
第一个参数fill-rule是可选的(需要注意的是第一个参数与后面的参数需要加上逗号分隔),用于指定多边形内部区域识别的算法,有以下选项:
nonzero:默认值evenodd
关于nonzero和evenodd算法之间的区别,可以参考:fill-rule - SVG | MDN
;
第二个参数则是一组坐标值,坐标值就是多边形的顶点位置,一个顶点坐标有两个值,用空格分隔,而不同顶点坐标之间则用逗号分隔;如:
1  | .demo {  | 
坐标值的原点位置是参考盒模型的左上角;
path
path函数则是利用SVG path语法来绘制形状和路径,不过目前兼容性很受限;语法如下:
path( [<‘fill-rule’>,]? <string> )[6]
第一个参数为可选的,用于指定fill-rule;第二个参数为SVG path字符串,用于指定路径;SVG path语法可以参考:d - SVG: Scalable Vector Graphics | MDN
插值规则
由于<basic-shape>数据类型是支持插值的,这就意味着该属性可以被应用到animation和transition属性中;但是插值规则并非可以直接从一种形状到另一种形状,只是对形状函数的参数数值进行插值而已;从W3C的文档[7]可知,basic-shape数据类型进行插值必须满足以下条件:
- 参考盒模型必须一致;
 - 形状类型必须一致;
 ellipse和circle的中心点位置不能包含closest-side和farthest-side关键词;polygon形状的fill-rule必须一致,且顶点数量要相同;
1  | .box {  | 

可以看到上面这种不同形状函数之间是不能进行插值的;
1  | .box {  | 

而上面这种同类型形状函数之间就可以进行数值插值了;
相关扩展
<position>数据类型
顾名思义,这种类型的数据专门用来表示位置的;语法[8]如下:

可以是一个值,也可以是两个值;一个值表示x位置和y位置是一致的,两个值则分别表示x位置和y位置;
x位置:可以是<length-percentage>(即长度类型 + 百分比类型)类型数据,还可以是left(0%),center(50%),right(100%)等关键词;y位置:可以是<length-percentage>,还可以是top(0%),center(50%),bottom(100%)等关键词·;
<shape-radius>数据类型
同理,该类型用于表示形状的半径长度,语法如下:
<shape-radius> = <length-percentage> | closest-side | farthest-side[9]
closest-side:半径长度为中心点到盒模型边框最近的一边之间的距离;farthest-side:半径长度为中心点到盒模型边框最远的一边之间的距离;
相关文档
- <basic-shape> - CSS(层叠样式表) | MDN
 - CSS Shapes Module Level 1
 - offset-path - CSS: Cascading Style Sheets | MDN
 - CSS的图形(Shape)概览 - CSS(层叠样式表) | MDN
 - shape-outside - CSS(层叠样式表) | MDN