basic-shape 数据类型

前言

<basic-shape>是一种特殊的CSS数据类型,用于表示使用基本形状函数,从而应用相应的形状或路径;目前支持<basic-shape>类型的属性有:

  • shape-outside:该属性用于指定周围内联元素环绕时所包围的形状
  • clip-path:该属性用于指定所属盒模型的裁剪形状
  • offset-path:该属性用于指定元素移动的路径,属于offset属性中的一个;

形状函数

关于参考盒模型

由于形状作用的盒模型根据具体的CSS属性有所不同,它可以是margin-boxpadding-boxborder-boxcontent-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
2
3
.demo {
clip-path: inset(20% round 45px);
}

circle

顾名思义,circle函数就是用于指定一个圆形形状,语法如下:

circle( <shape-radius>? [ at <position> ]? )[3]

参数依然是两个部分,第一个参数为半径,是可选的,默认值W3C文档上没有说明,但是据观察为盒模型的最短边的一半注意:这可与50%的效果是不一样的!);当使用百分比时,长度的参照值为:

height2+width2/2\sqrt{height^2 + width^2} / \sqrt{2}

这里的宽度和高度指的都是参考盒模型;后面一个参数也是可选的,为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

关于nonzeroevenodd算法之间的区别,可以参考:fill-rule - SVG | MDN
;

第二个参数则是一组坐标值,坐标值就是多边形的顶点位置,一个顶点坐标有两个值,用空格分隔,而不同顶点坐标之间则用逗号分隔;如:

1
2
3
.demo {
clip-path: polygon(50% 20%, 90% 80%, 10% 80%);
}

坐标值的原点位置是参考盒模型的左上角;

path

path函数则是利用SVG path语法来绘制形状和路径,不过目前兼容性很受限;语法如下:

path( [<‘fill-rule’>,]? <string> )[6]

第一个参数为可选的,用于指定fill-rule;第二个参数为SVG path字符串,用于指定路径;SVG path语法可以参考:d - SVG: Scalable Vector Graphics | MDN

插值规则

由于<basic-shape>数据类型是支持插值的,这就意味着该属性可以被应用到animationtransition属性中;但是插值规则并非可以直接从一种形状到另一种形状,只是对形状函数的参数数值进行插值而已;从W3C的文档[7]可知,basic-shape数据类型进行插值必须满足以下条件:

  • 参考盒模型必须一致
  • 形状类型必须一致
  • ellipsecircle的中心点位置不能包含closest-sidefarthest-side关键词;
  • polygon形状的fill-rule必须一致,且顶点数量要相同
1
2
3
4
5
6
7
8
9
10
11
.box {
width: 200px;
height: 80px;
clip-path: inset(10px round 20px);
background-color: coral;
cursor: pointer;
transition: clip-path .5s ease-in;
}
.box:hover {
clip-path: ellipse();
}

img

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

1
2
3
4
5
6
7
8
9
10
11
.box {
width: 200px;
height: 80px;
clip-path: inset(10px round 20px);
background-color: coral;
cursor: pointer;
transition: clip-path .5s ease-in;
}
.box:hover {
clip-path: inset(20px round 20px);
}

img

而上面这种同类型形状函数之间就可以进行数值插值了;

相关扩展

<position>数据类型

顾名思义,这种类型的数据专门用来表示位置的;语法[8]如下:

img

可以是一个值,也可以是两个值;一个值表示x位置和y位置是一致的,两个值则分别表示x位置和y位置;

  • x位置:可以是<length-percentage>(即长度类型 + 百分比类型)类型数据,还可以是left0%),center50%),right100%)等关键词;
  • y位置:可以是<length-percentage>,还可以是top0%),center50%),bottom100%)等关键词·;

<shape-radius>数据类型

同理,该类型用于表示形状的半径长度,语法如下:

<shape-radius> = <length-percentage> | closest-side | farthest-side[9]

  • closest-side:半径长度为中心点到盒模型边框最近的一边之间的距离
  • farthest-side:半径长度为中心点到盒模型边框最远的一边之间的距离

相关文档


  1. https://drafts.csswg.org/css-shapes/#reference-box ↩︎

  2. https://drafts.csswg.org/css-shapes/#funcdef-inset ↩︎

  3. https://drafts.csswg.org/css-shapes/#funcdef-circle ↩︎

  4. https://drafts.csswg.org/css-shapes/#funcdef-ellipse ↩︎

  5. https://drafts.csswg.org/css-shapes/#funcdef-polygon ↩︎

  6. https://drafts.csswg.org/css-shapes/#funcdef-path ↩︎

  7. https://drafts.csswg.org/css-shapes/#basic-shape-interpolation ↩︎

  8. https://drafts.csswg.org/css-values-3/#position ↩︎

  9. https://drafts.csswg.org/css-shapes/#typedef-shape-radius ↩︎