惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

量子位
雷峰网
雷峰网
博客园 - 三生石上(FineUI控件)
月光博客
月光博客
有赞技术团队
有赞技术团队
阮一峰的网络日志
阮一峰的网络日志
Last Week in AI
Last Week in AI
G
Google Developers Blog
腾讯CDC
B
Blog
Microsoft Azure Blog
Microsoft Azure Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
Microsoft Security Blog
Microsoft Security Blog
人人都是产品经理
人人都是产品经理
博客园_首页
T
Tailwind CSS Blog
C
Check Point Blog
博客园 - 【当耐特】
MongoDB | Blog
MongoDB | Blog
A
About on SuperTechFans
Y
Y Combinator Blog
L
LangChain Blog
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI

张鑫旭-鑫空间-鑫生活

1分钟速度了解text-align match-parent声明 « 张鑫旭-鑫空间-鑫生活 光标的形状也能设置了,就是CSS caret-shape属性 « 张鑫旭-鑫空间-鑫生活 pretext与文字四面环绕效果的实现 « 张鑫旭-鑫空间-鑫生活 JSON.rawJSON方法的作用是什么? « 张鑫旭-鑫空间-鑫生活 如何使用CSS判断鼠标从哪个方向进入元素? « 张鑫旭-鑫空间-鑫生活 借助mediabunny纯JS实现视频水印、剪裁、合成等功能 « 张鑫旭-鑫空间-鑫生活 务必谨慎使用JS WeakRef弱引用 « 张鑫旭-鑫空间-鑫生活 CSS六边形头像的实现与蜂巢布局 « 张鑫旭-鑫空间-鑫生活 CSS corner-shape与背景底纹技术 « 张鑫旭-鑫空间-鑫生活 浅学WebTransport API:下一代Web双向通信技术 « 张鑫旭-鑫空间-鑫生活 HTML dialog元素新支持了closedBy属性 « 张鑫旭-鑫空间-鑫生活 HTML interestfor属性与悬停popover交互效果 « 张鑫旭-鑫空间-鑫生活 CSS3模拟window7炫酷界面效果展示 « 张鑫旭-鑫空间-鑫生活 图片旋转+剪裁js插件(兼容各浏览器) « 张鑫旭-鑫空间-鑫生活 纯js无图片无外链CSS图片幻灯片播放插件 « 张鑫旭-鑫空间-鑫生活 CSS border三角、圆角图形生成技术简介 « 张鑫旭-鑫空间-鑫生活 CSS “渐进增强”在web制作中常见应用举例 « 张鑫旭-鑫空间-鑫生活 让IE6/IE7/IE8浏览器支持CSS3属性 « 张鑫旭-鑫空间-鑫生活 jQuery – 高亮动态显示页面HTML代码插件 « 张鑫旭-鑫空间-鑫生活 翻译 – 逐渐消失的Flash网站 « 张鑫旭-鑫空间-鑫生活 CSS reset的重新审视 – 避免样式重置 « 张鑫旭-鑫空间-鑫生活 新浪微博插入话题后部分文字选中的js实现 « 张鑫旭-鑫空间-鑫生活 JavaScript实现http地址自动检测并添加URL链接 « 张鑫旭-鑫空间-鑫生活 CSS实现兼容性的渐变背景(gradient)效果 « 张鑫旭-鑫空间-鑫生活 CSS content内容生成技术以及应用 « 张鑫旭-鑫空间-鑫生活 CSS gradient渐变之webkit核心浏览器下的使用 « 张鑫旭-鑫空间-鑫生活 CSS渐变之CSS3 gradient在Firefox3.6下的使用 « 张鑫旭-鑫空间-鑫生活 区分IE8/IE7/IE6及其他浏览器-CSS “\9″hack « 张鑫旭-鑫空间-鑫生活 CSS实现跨浏览器兼容性的盒阴影效果 « 张鑫旭-鑫空间-鑫生活 CSS3&HTML5各浏览器支持情况一览表 « 张鑫旭-鑫空间-鑫生活
介绍一种全新的clipPath Sprites小图标技术 « 张鑫旭-鑫空间...
张鑫旭,zhangxinxu · 2020-10-30 · via 张鑫旭-鑫空间-鑫生活

by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=9539
本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。

剪裁图标合集技术

目前流行的SVG小图标技术是SVG Sprites技术,此技术我6年前就率先在国内进行了介绍:“未来必热:SVG Sprites技术介绍”,这里再介绍另外一种同样需要用到SVG元素的Sprites技术,我称之为“clipPath Sprites技术”。

一、关于clip-path与小图标实现

CSS clip-path属性除了剪裁圆、多边形之外,还支持url()函数语法,可以把SVG元素中的路径作为剪裁路径。

语法示意如下:

.shape {
    clip-path: url(#someId);
}

someId就是SVG中<clipPath>元素的ID值。

例如:

<svg>
  <clipPath id="someId">...</clipPath>
</svg>

下面通过一个具体案例演示下这种语法的效果。

假设有如下SVG代码:

<svg width="50" height="50" version="1.1" xmlns="http://www.w3.org/2000/svg">
    <ellipse cx="25" cy="25" rx="20" ry="10"></ellipse>
    <rect x="15" y="5" width="20" height="40" rx="5" ry="5"></rect>
</svg>

会有如下图所示的姨妈巾效果:

SVG元素图形效果示意

此时,可以把SVG中的图形元素全部放在<clipPath>元素中,这样,就可以把任意的元素剪裁为姨妈巾的形状了。

<svg width="0" height="0">
  <clipPath id="someId">
    <ellipse cx="25" cy="25" rx="20" ry="10"></ellipse>
    <rect x="15" y="5" width="20" height="40" rx="5" ry="5"></rect>
  </clipPath>
</svg>

但是,实际测试发现,上面的代码只有在50px*50px的元素中效果才是正常的,也就是剪裁元素的尺寸默认需要和SVG元素图形尺寸一致才行,这就有些坑爹了,好在SVG提供了一些方法可以适用于任意的HTML元素尺寸。

方法1:transform缩放SVG

例如剪裁的HTML元素的尺寸是20px*20px,原SVG尺寸是50px,因此,需要缩放40%,此时就有如下所示的SVG代码:

<svg width="0" height="0">
  <clipPath id="someId">
    <ellipse transform="scale(0.4, 0.4)" cx="25" cy="25" rx="20" ry="10"></ellipse>
    <rect transform="scale(0.4, 0.4)" x="15" y="5" width="20" height="40" rx="5" ry="5"></rect>
  </clipPath>
</svg>

此时,就可以把20px*20px大小元素剪裁成对应规格的图形效果了:

.icon {
    display: inline-block;
    width: 20px; height: 20px;
    background-color: deepskyblue;
    clip-path: url(#someId);
}

此时就有如下图所示的效果:

transform缩放下的图标效果

方法2:设置clipPathUnits=”objectBoundingBox”

设置剪裁位置是基于对象的尺寸,此时,需要SVG图形中的坐标都以数值1为基准进行计算,因此,通常路径或者参数值基本上都是小于1的数值,例如:

<svg width="0" height="0">
  <clipPath id="someId" clipPathUnits="objectBoundingBox">
    <ellipse cx=".5" cy=".5" rx=".4" ry=".2"></ellipse>
    <rect x=".3" y=".1" width=".4" height=".8" rx=".1" ry=".1"></rect>
  </clipPath>
</svg>  

此时,剪裁的图形效果会按照元素的的尺寸计算,无论图标的尺寸是20px*20px,还是100px*100px,都会按照这个尺寸进行剪裁。

实现的效果如下截图所示:

图标效果示意

眼见为实,您可以狠狠地点击这里:2种方法实现的clip-path小图标剪裁效果demo

无论是transform缩放,还是objectBoundingBox重计算,都可以实现任意尺寸的SVG剪裁效果。

下图是Firefox浏览器下的效果截图:

clip-path实现小图标效果示意

//zxx: 如果你看到这段文字,说明你现在访问是体验糟糕的垃圾盗版网站,你可以访问原文获得很好的体验:https://www.zhangxinxu.com/wordpress/?p=9539(作者张鑫旭)

关于IE/Edge浏览器

CSS中有3个很高级属性IE浏览器也是支持的,分别是clip-path属性,filter属性和mask属性。

但是,请注意,这些支持其实并不是CSS规范中的那种支持,而是SVG元素衍生过来的语法,因为IE浏览器支持SVG,而SVG中有一些特性可以在CSS中使用,因此,IE浏览器也支持了部分高级CSS语法,就好像SVG中的fillstroke属性也可以在IE中使用一样。

同样的,clip-path属性,filter属性和mask属性都是仅支持url()语法,均指向SVG元素。

因此,虽然clip-path:url(#someId)在IE/Edge浏览器下语法是合法的,但是仅仅作用在SVG元素上才有效果,也就是下面的HTML代码IE浏览器是没有效果的:

<i class="icon"></i>

但是下面的代码就有剪裁效果:

<svg width="20" height="20">
  <rect fill="deepskyblue" class="icon"></rect>
</svg>

因此,如果需要兼容IE浏览器,只要把普通HTML元素改为使用SVG元素就可以了。

二、更进一步,clipPath Sprites小图标技术

在传统的SVG Sprites中使用的是SVG <use>元素的href属性值指向<symbol>元素的id属性,嘿!岂不是和这里的实现逻辑本质上是一样的,这里是CSS clip-path属性中的url()函数值指向<clipPath>元素的id属性。

因此,理论上,传统SVG Sprites合并那一套东西也是可以用在clipPath Sprites合并中的。

受此idea的启发,我就把我之前制作的SVG压缩合并工具升级了下,增加了clipPath Sprites合并功能(选择的是transform缩放,因为更容易实现[捂脸]),发现这个技术完全可行。

您可以狠狠地点击这里:升级后的SVG在线压缩合并工具

从这个我做的SVG Sprites还原工具中下载几个比较顺眼的图标,然后拖进去——

图标拖拽进去示意

在页面的最下方就可以看到合并后的clipPath Sprites代码了,如下截图示意:

clipPath Sprites代码示意

点击复制或下载按钮,把输入框中的SVG代码复制到页面中,此时,就可以使用CSS clip-path属性实现各式各样的小图标效果了。

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="0" height="0" style="position:absolute;">
    <clipPath id="eye"><path transform="scale(0.034724, 0.0390625)" d="..."/></clipPath>
    <clipPath id="paper-plane"><path transform="scale(0.0390625, 0.0390625)" d="..."/></clipPath>
    <clipPath id="comment"><path transform="scale(0.0390625, 0.0390625)" d="..."/></clipPath>
</svg>  

例如有如下所示的HTML和CSS代码:

<ul id="ul">
    <li><i class="icon" style="--clipPath:url(#paper-plane)"></i>分享</li>
    <li><i class="icon" style="--clipPath:url(#eye)"></i>预览</li>
    <li><i class="icon" style="--clipPath:url(#comment)"></i>评论</li>
</ul>
.icon {
    display: inline-block;
    width: 20px; height: 20px;
    background-color: currentColor;
    -webkit-clip-path: var(--clipPath);
    clip-path: var(--clipPath);
    vertical-align: middle;
    margin-right: 1ch;
}

此时就有如下图所示的小图标效果:

小图标效果实现示意

眼见为实,有演示的,您可以狠狠地点击这里:SVG clipPath合并图标效果demo

由于是通过剪裁实现的,因此实现的图标效果支持任意变色,如下GIF录屏示意(点击播放317K):

颜色变化GIF录屏示意

也可以是渐变效果(改成背景渐变即可),例如:

.icon {
    background: linear-gradient(deepskyblue, deeppink);
    ...
}

渐变效果如下截图:

渐变截图效果

当然,也可以把照片剪裁成图标模板,或者是任意的元素,按钮、文字等都可以剪裁成小图标的样子,非常灵活。

对比传统SVG Sprites技术

传统SVG Sprites clipPath Sprites
矢量
颜色可变
支持渐变
标签 svg>use 任意HTML标签(IE除外)
兼容性 IE9+ IE9+(IE需使用SVG元素)
尺寸控制 灵活 transform方法受限 | clipPathUnits方法灵活
工具 丰富 ✔ 起步中……

整体来看,clipPath Sprites技术的优势更强,尤其在移动端开发中,只要后期有转换工具可以把所有的SVG图标路径转成clipPathUnits为objectBoundingBox模式的数值,那么clipPath Sprites技术几乎就没有任何缺陷,取代传统的SVG Sprites小图标技术应该不成问题。

三、肝不动的结语

本月爆更11篇技术文章,10年来新高,为什么高产四母猪呢?因为《CSS新世界》这本书交稿了,有时候更新博客了,于是积攒的文章一次性爆发了,不过也导致这个月天天很晚睡,实在有些肝不动了。

回到文章这里,clipPath Sprites技术是自己写CSS clip-path章节突然的灵感,我查了下国内外的资料,有使用clip-path实现小图标效果的案例,但是并没有发现谁把小图标全部打包在一起的案例,因此,本文的clipPath Sprites技术可以算是一个首创的技术吧。

不过,也是最近刚折腾出来的,还没有在生成环境使用,因此,是否有什么坑还不得而知,不过按照我长期以来使用clip-path的经验来看,应该没什么问题,clip-path一直是一个运行非常稳健的CSS属性,在移动端兼容性也非常好。

我近期会在合适的项目中尝试这种图标技术,之后有变化会进一步更新。

OK,结语就说这么多。

如果你觉得本文内容确实有点料,欢迎分享,也欢迎以评论方式进行交流,补充我不知道的信息,或者指出文章有表述不准确的地方。

本文为原创文章,欢迎分享,勿全文转载,如果实在喜欢,可收藏,永不过期,且会及时更新知识点及修正错误,阅读体验也更好。
本文地址:https://www.zhangxinxu.com/wordpress/?p=9539

(本篇完)