CSS小图标剪裁终极解决方案clip-path shape()函数

这篇文章发布于 2025年06月30日,星期一,16:35,归类于 CSS相关。 阅读 209 次, 今日 209 次 没有评论

 

clip-path shape函数封面图

一、告别path函数

clip-pathpath()函数可以传入SVG路径,从而实现元素的剪裁效果,比方说SVG小图标。

例如:

clip-path: path("M 0 200 L 0,75 A 5,5 0,0,1 150,75 L 200 200 z");

我多年前,我去,看了下,已经5年了,2020年的时候,有基于路径剪裁,研究了下“clipPath Sprites小图标技术”,还制作了配套的转换工具。

但是最后实践下来,这个技术无人问津,包括我自己也不使用,原因就在于尺寸控制太麻烦。

目前主流就是两种,一种是SVG图标元素直接内容,一种是CSS背景转移使用遮罩实现。

这两种技术尺寸控制都非常方便,前者直接CSS尺寸设置,后者通过background-size等属性进行设置。

path()函数的尺寸问题

使用path()函数,或使用url()函数执行SVG元素的<path>元素,都有尺寸无法自适应的问题。

因为SVG路径里面的数值都是固定的像素px大小,在SVG元素中,这些大小与SVG外部尺寸关联,不会有问题,但是,放在CSS图像中,那就问题大了。

例如,Font Awesome小图标SVG基本尺寸都是512*512,其path坐标值都是好几百的值。

但是,CSS小图标的尺寸是20*20,如果应用几百数值的剪裁路径,小图标肯定就有问题,对不对?

要么path坐标等比例缩小,要么CSS小图标尺寸也设成512像素,然后再zoom缩放,但这样实现就很麻烦。

于是,在这个背景下,clip-path的shape()函数应运而生。

二、shape()函数的优势

不妨对比下面两段剪裁应用代码,前者path()函数,后者shape()函数。

.use-path {
  clip-path: path('M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z');
}
.use-shape {
  clip-path: shape(from 50% 0%,curve to 0% 50% with 22.38% 0%/0% 22.38%,smooth by 50% 50% with 22.38% 50%,smooth by 50% -50% with 50% -22.38%,smooth to 50% 0% with 77.62% 0%,close);
}

实现的都是圆形效果,如下图所示:

区别在于,shape函数的指令不再是字符串,而是可自由调节的指令片段,就很自由。以及,shape函数的值是支持百分比值的,不再是固定的值,这个非常重要!

因为这就意味着,当任意尺寸的元素应用shape()函数的时候,剪裁的效果都是自动适应的,path()函数的尺寸问题将不复存在。

指令转换

上面的shape()函数中出现的单词from、curve、smooth等,其实与SVG的曲线绘制指令是一一对应的,这是我整理的对应关系表,极其含义,希望可以帮到大家的学习。

原始命令 名称 shape指令
M/m 移动到/移动 from to/from by
Z或z closepath 关闭路径 close
L/l 画线到/画线 line to/line by
H/h 水平线到/水平线 hline to/hline by
V/v 垂直线到/垂直线 vline to/vline by
C/c、Q/q、T/t 三次贝塞尔曲线、二次贝塞尔曲线、光滑二次贝塞尔曲线 均是curve to/curve by,具体参数不同
S/s 光滑三次贝塞尔曲线 smooth to/smooth by
A/a 椭圆弧 arc to/arc by

还支持任意CSS数学函数

shape()函数不仅支持百分比值,还支持calc计算、round 等数学函数,可以和CSS变量混合,示意:

.flag {
  --size: 40px;
  clip-path: shape(
    from 0px var(--size),
    curve to 100% var(--size) 
          with 25% 0px / 75% calc(var(--size) * 2),
    vline to calc(100% - var(--size)),
    curve to 0 calc(100% - var(--size))
          with 75% 100% / 25% calc(100% - var(--size) * 2),
    close
  )
}

因此,实现动画效果也非常方便,只需要使用@property规则,让CSS变量为数值类型就好了,详见此文:“Nice! Safari也支持CSS @property规则了

三、放心,有转换工具

对于大多数前端开发人员而言,SVG的路径指令就是天书,看都看不到,还要转换成shape指令,岂不是要了他的狗命。

不要担心,对此,我专门做了个在线的转换工具,当当当当。

您可以狠狠地点击这里:CSS clip-path path() to shape()函数转换工具

粘贴滤镜,点击转换按钮,然后点击复制就好了,右半区有演示页面,还支持直接上传SVG文件提取路径,如下截图所示:

演示页面效果截图

工具开发的匆忙,有什么使用问题,欢迎反馈,有什么建议和需求,也可以评论提出,我会抽空更新的哈。

四、兼容性、点评与结语

shape()函数这个特性还比较新,我没有在caniuse上找到兼容性截图,不过支持数据还是有的,Chrome 135 和 Safari 18.4都有已经支持。

只要这两个浏览器支持了,那就好说了,基本上,不出两年就可以再生产环境使用了。

配合前端流工具,以后的小图标实现方案又多了一种选择。

相比遮罩,clip-path的语义要更好,理解更方便,上手也更简单。

我还是比较看好shape()函数的应用前景的。

好,就说这么多吧,本文还是值得转发转发的!

妈呀,银月照片还没出来,先用这个代替吧。

银月半个头

(本篇完)

分享到:


发表评论(目前没有评论)