clipPath 必须定义在 <defs> 中才能复用;内部形状默认 nonzero 填充规则,镂空需显式设 fill-rule="evenodd";CSS 引用时 url(#id) 格式须严格,且仅对块级元素生效;跨 SVG 实例不可引用,坐标系默认为用户坐标系。

clipPath 必须定义在 里才能复用
直接写在
正确做法是把 <clipPath> 包进 <defs>,再通过 clip-path CSS 属性或 clip-path SVG 属性引用:
<svg>
<defs>
<clipPath id="circle-clip">
<circle cx="50" cy="50" r="30"/>
</clipPath>
</defs>
<rect x="0" y="0" width="100" height="100" clip-path="url(#circle-clip)"/>
</svg>
clipPath 内部形状默认使用 nonzero 填充规则
这意味着如果剪切路径由多个嵌套路径组成(比如一个大圆里挖一个小圆),结果取决于路径绘制方向。顺时针 + 逆时针混用容易意外保留不该显示的区域。
稳妥做法是显式声明 fill-rule="evenodd",尤其处理镂空效果时:
立即学习“前端免费学习笔记(深入)”;
<clipPath id="donut-clip" fill-rule="evenodd"> <circle cx="50" cy="50" r="40"/> <circle cx="50" cy="50" r="20"/> </clipPath>
-
fill-rule="evenodd"能正确识别“外圈减内圈”的环形裁剪 -
fill-rule="nonzero"下,两个同心圆方向相同时会整体填充,失去镂空效果 - Chrome/Firefox 对
fill-rule支持一致,但 Safari 旧版本对clipPath内fill-rule解析偶有偏差,建议测试
clip-path CSS 属性引用 clipPath 时 url() 必须带协议前缀
用 CSS 的 clip-path 指向 SVG 内定义的 <clipPath>,url() 写法不能省略 #,也不能加引号或空格:
- ✅ 正确:
clip-path: url(#circle-clip) - ❌ 错误:
clip-path: url(#circle-clip)(多了一个空格) - ❌ 错误:
clip-path: url('#circle-clip')(加了单引号) - ❌ 错误:
clip-path: url(circle-clip)(漏掉#)
注意:该 CSS 属性只对块级或 inline-block 元素生效;<img> 或 <div> 需要明确设置 display: block 或类似值,否则裁剪可能不触发。
clipPath 无法直接作用于外部 SVG 或 HTML 元素(除非用 CSS)
<clipPath> 是 SVG 容器内的资源,不能跨 <svg> 实例引用。比如页面有两个独立 <svg>,第二个里定义的 clipPath 无法被第一个里的元素通过 url(#id) 引用。
常见绕过方式:
- 把
<defs>和<clipPath>提到公共位置,例如放在页面顶部的隐藏<svg>中 - 改用 CSS
clip-path配合path()或polygon()函数,避开 SVG 引用限制(但兼容性稍弱) - 服务端或构建时内联所有依赖的
<clipPath>,确保每个需要它的<svg>都自带定义
最易被忽略的是:SVG clipPath 的坐标系默认是用户坐标系(userSpaceOnUse),不是对象边界盒(objectBoundingBox)。如果没设 clipPathUnits="objectBoundingBox",那 <circle cx="0.5" cy="0.5" r="0.3"> 这类相对单位会失效——它真按像素算,而不是按被裁剪元素宽高比例算。



















