clip-path · 裁剪clip-path 进阶:fill-rule、参照盒与形状动画
裁剪的基本用法见 basic-shape 形状函数一页——形状内保留、形状外透明(被裁掉的区域也不响应点击)。这页讲四个实际使用时才会遇到的细节:自交路径算谁是「内部」(fill-rule)、形状相对哪个盒子算(geometry-box)、怎么让 path 随盒子缩放(url +
objectBoundingBox)、以及什么时候 clip-path 能平滑过渡。
1 · fill-rule 的两套内部判定
路径一旦自相交或者有多段子路径,「内部」就不再显然。两套裁决规则:nonzero(默认)从该点发射线,数边界带方向的净穿越数,非零算内部——所以「反着画的内圈」能把净数抵成 0,挖出洞;evenodd 不看方向只数次数,奇数内、偶数外。两组对照:
nonzero 与 evenodd 两套内部判定规则的差别。可切换规则,观察自相交路径与多段子路径下哪些区域被算作内部。fill-rule 写在形状函数的第一个参数位:polygon(evenodd, …)、path(evenodd, "…"),新的 shape() 同理;圆和矩形永远不自交,没有这个参数。
实测警告(Chrome 151,核对于 2026-08):Chromium 系能解析 path(evenodd, "…"),但绘制时忽略这个 fill-rule 参数(恒按 nonzero;而命中测试又遵循它——绘制与点击区域不一致)。polygon() 的 fill-rule 没有此问题,上面五角星就是用它演示的。所以要在
path() 里挖洞,跨浏览器最可靠的是右侧方案:把内圈反向绘制,nonzero 自然把净穿越数抵成 0。
2 · geometry-box 与参照盒
形状的百分比 / 原点默认参照 border-box。在形状函数后面补一个关键字就能换参照盒——同一个 circle(50%),参照盒越大圆越大:
circle(50%) 在不同参照盒下的大小。可切换 geometry-box 关键字,参照盒越大圆越大。
geometry-box 也能单独使用:clip-path: content-box 直接裁成内容盒矩形。另有三个源自 SVG 的值 fill-box / stroke-box / view-box,参照 SVG 元素的几何;用在 HTML 元素上时 fill-box 折算为 content box、另两个折算为 border box。注意 margin-box
只是把参照系放大——margin box 比 border box 大,参照系放大之后裁掉的更少:box-shadow、outline 与溢出的后代内容这些本会被 border box 裁掉的绘制会重新露出来,所以它只会让裁得更少,不会凭空多画。
3 · url(#clipPath):借助 SVG 让 path 随盒子缩放
path() 的坐标固定为 px,盒子一变宽心形就不再居中。把路径放进 SVG 的 <clipPath clipPathUnits="objectBoundingBox">(坐标全用 0~1),再用 clip-path: url(#heart) 引用——形状就按盒子比例伸缩了:
<clipPath> 并用 `clipPathUnits=4 · 形状动画:顶点数相同才平滑
clip-path 可以 transition / animation,但两个形状要能插值:同一个函数、同样的「结构」(polygon 顶点数一致、path 命令序列一致)。结构不同只能跳变:
5 · 附:clip-path vs mask
clip-path 与 mask 的对照。前者是硬边界的几何裁切,后者按亮度或 alpha 逐像素调制。