为了方便图标管理,往往会把众多小图标合在一个SVG元素中,这种处理技术称为“ClipPath Sprites技术”。
实现原理:使用clip-path对合并后的内联svg图标进行裁剪显示。
注意事项:
内联的SVG元素不能使用display:none
或者visibility:hidden
进行隐藏,否则剪裁元素会被隐藏,并且此技术只适合填充模式的小图标,不适合描边小图标。
1. 合并图标得到ClipPath Sprites代码
打开图标合并工具 https://www.zhangxinxu.com/sp/svgo/
通过上传或粘贴的方式,将原始svg小图标添加到合并工具中,工具会自动生成ClipPath Sprites代码
- 原始svg小图标可以从阿里图标库 、Font Awesome图标库 等图标库中下载/复制svg代码。
例如添加了以下两个图标
自动生成的ClipPath Sprites代码在工具最下方
2. 将ClipPath Sprites代码复制粘贴到页面中
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="0"
height="0"
style="position:absolute;"
>
<clipPath id="1636507720028" fill="none">
<path
transform="scale(0.044643, 0.039063)"
d="M439.39 362.29c-19.32-20.76-55.47-51.99-55.47-154.29 0-77.7-54.48-139.9-127.94-155.16V32c0-17.67-14.32-32-31.98-32s-31.98 14.33-31.98 32v20.84C118.56 68.1 64.08 130.3 64.08 208c0 102.3-36.15 133.53-55.47 154.29-6 6.45-8.66 14.16-8.61 21.71.11 16.4 12.98 32 32.1 32h383.8c19.12 0 32-15.6 32.1-32 .05-7.55-2.61-15.27-8.61-21.71zM67.53 368c21.22-27.97 44.42-74.33 44.53-159.42 0-.2-.06-.38-.06-.58 0-61.86 50.14-112 112-112s112 50.14 112 112c0 .2-.06.38-.06.58.11 85.1 23.31 131.46 44.53 159.42H67.53zM224 512c35.32 0 63.97-28.65 63.97-64H160.03c0 35.35 28.65 64 63.97 64z"
/>
</clipPath>
<clipPath id="1636507708197" fill="none">
<path
transform="scale(0.044643, 0.039063)"
d="M436 160c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20V48c0-26.5-21.5-48-48-48H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h320c26.5 0 48-21.5 48-48v-48h20c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20v-64h20c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20v-64h20zm-68 304H48V48h320v416zM208 256c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm-89.6 128h179.2c12.4 0 22.4-8.6 22.4-19.2v-19.2c0-31.8-30.1-57.6-67.2-57.6-10.8 0-18.7 8-44.8 8-26.9 0-33.4-8-44.8-8-37.1 0-67.2 25.8-67.2 57.6v19.2c0 10.6 10 19.2 22.4 19.2z"
/>
</clipPath>
</svg>
为了方便区分图标,你可以将id修改为图标的名称(中英文不限)
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="0"
height="0"
style="position:absolute;"
>
<clipPath id="小铃铛" fill="none">
<path
transform="scale(0.044643, 0.039063)"
d="M439.39 362.29c-19.32-20.76-55.47-51.99-55.47-154.29 0-77.7-54.48-139.9-127.94-155.16V32c0-17.67-14.32-32-31.98-32s-31.98 14.33-31.98 32v20.84C118.56 68.1 64.08 130.3 64.08 208c0 102.3-36.15 133.53-55.47 154.29-6 6.45-8.66 14.16-8.61 21.71.11 16.4 12.98 32 32.1 32h383.8c19.12 0 32-15.6 32.1-32 .05-7.55-2.61-15.27-8.61-21.71zM67.53 368c21.22-27.97 44.42-74.33 44.53-159.42 0-.2-.06-.38-.06-.58 0-61.86 50.14-112 112-112s112 50.14 112 112c0 .2-.06.38-.06.58.11 85.1 23.31 131.46 44.53 159.42H67.53zM224 512c35.32 0 63.97-28.65 63.97-64H160.03c0 35.35 28.65 64 63.97 64z"
/>
</clipPath>
<clipPath id="电话簿" fill="none">
<path
transform="scale(0.044643, 0.039063)"
d="M436 160c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20V48c0-26.5-21.5-48-48-48H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h320c26.5 0 48-21.5 48-48v-48h20c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20v-64h20c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20v-64h20zm-68 304H48V48h320v416zM208 256c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm-89.6 128h179.2c12.4 0 22.4-8.6 22.4-19.2v-19.2c0-31.8-30.1-57.6-67.2-57.6-10.8 0-18.7 8-44.8 8-26.9 0-33.4-8-44.8-8-37.1 0-67.2 25.8-67.2 57.6v19.2c0 10.6 10 19.2 22.4 19.2z"
/>
</clipPath>
</svg>
3. 在页面中渲染小图标
使用i标签进行渲染,样式为自定义的myIcon,在style的css变量–clipPath中,url()函数引用对应图标的id即可。
<i class="myIcon" style="--clipPath:url(#电话簿)"></i>
.myIcon {
display: inline-block;
width: 20px;
height: 20px;
background-color: currentColor;
clip-path: var(--clipPath);
vertical-align: middle;
margin-right: 1ch;
}
页面效果为
完整代码范例
<template>
<div>
<ul>
<li><i class="myIcon" style="--clipPath:url(#电话簿)"></i>电话簿</li>
<li><i class="myIcon" style="--clipPath:url(#小铃铛)"></i>小铃铛</li>
</ul>
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
width="0"
height="0"
style="position:absolute;"
>
<clipPath id="小铃铛" fill="none">
<path
transform="scale(0.044643, 0.039063)"
d="M439.39 362.29c-19.32-20.76-55.47-51.99-55.47-154.29 0-77.7-54.48-139.9-127.94-155.16V32c0-17.67-14.32-32-31.98-32s-31.98 14.33-31.98 32v20.84C118.56 68.1 64.08 130.3 64.08 208c0 102.3-36.15 133.53-55.47 154.29-6 6.45-8.66 14.16-8.61 21.71.11 16.4 12.98 32 32.1 32h383.8c19.12 0 32-15.6 32.1-32 .05-7.55-2.61-15.27-8.61-21.71zM67.53 368c21.22-27.97 44.42-74.33 44.53-159.42 0-.2-.06-.38-.06-.58 0-61.86 50.14-112 112-112s112 50.14 112 112c0 .2-.06.38-.06.58.11 85.1 23.31 131.46 44.53 159.42H67.53zM224 512c35.32 0 63.97-28.65 63.97-64H160.03c0 35.35 28.65 64 63.97 64z"
/>
</clipPath>
<clipPath id="电话簿" fill="none">
<path
transform="scale(0.044643, 0.039063)"
d="M436 160c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20V48c0-26.5-21.5-48-48-48H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h320c26.5 0 48-21.5 48-48v-48h20c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20v-64h20c6.6 0 12-5.4 12-12v-40c0-6.6-5.4-12-12-12h-20v-64h20zm-68 304H48V48h320v416zM208 256c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm-89.6 128h179.2c12.4 0 22.4-8.6 22.4-19.2v-19.2c0-31.8-30.1-57.6-67.2-57.6-10.8 0-18.7 8-44.8 8-26.9 0-33.4-8-44.8-8-37.1 0-67.2 25.8-67.2 57.6v19.2c0 10.6 10 19.2 22.4 19.2z"
/>
</clipPath>
</svg>
</div>
</template>
<style scoped>
.myIcon {
display: inline-block;
width: 20px;
height: 20px;
background-color: currentColor;
clip-path: var(--clipPath);
vertical-align: middle;
margin-right: 1ch;
}
</style>