发布时间:2025 年 4 月 8 日
借助 clip-path
属性,您可以通过剪裁到圆形、多边形甚至 SVG 路径来更改元素的形状。不过,在 Chrome 135 和 Safari 18.4 之前,您必须在响应式多边形和使用 SVG 路径的非响应式更复杂形状之间进行选择。借助新的 shape()
函数,clip-path
可以将元素剪裁为响应式的非多边形形状。
创建旗形
例如,比较使用 clip-path: path()
和 clip-path: shape()
创建旗形。
旗形并非严格意义上的多边形,因为其顶部和底部边界是立方贝塞尔曲线,而不是直线或圆角。
使用 clip-path: path()
创建标志
此标志等形状可以使用 SVG 路径表示:
.flag {
clip-path: path(
"M 0 20 \
C 25 0 75 40 100 20 \
V 80 \
C 75 100 25 60 0 80 \
z");
}
具体而言,SVG 路径是一系列路径命令:
- 移动到 0, 20。
- 使用控制点 (25,0 和 75, 40) 曲线到 100, 20。
- 垂直线为 80。
- 使用控制点 (75,100 和 25,50) 将曲线绘制到 0, 80。
- 关闭路径(线条到 0,20)。
这会绘制一个旗形,但所有单位均为像素。SVG 可以将这些像素放大到视口盒,但方式始终看起来像是整个形状的几何放大。
例如,如果您希望整个矩形进行缩放,但要保持曲线的高度和宽度为 20 像素,则 SVG 无法胜任此任务。
使用 shape()
创建标志
使用 shape()
比较相同的结果。形状函数接受一系列命令,类似于 SVG 路径命令。不过,这些命令接受任何 CSS 单位的 CSS 长度和百分比。
以下 CSS 会将标志转换为使用百分比单位的 shape()
:
.flag {
clip-path: shape(from 0% 20%,
curve to 100% 20% with 25% 0% / 75% 40%,
vline to 80%,
curve to 0% 80% with 75% 100% / 25% 60%,
close
);
}
让其具有响应能力
您可以从 CSS 长度范围中选择要为每个坐标使用的长度。
例如,如需让标志的整个大小按元素的大小进行缩放,但保持曲线的高度不变,您可以执行以下操作:
.flag {
clip-path: shape(from 0% 20px,
curve to 100% 20px with 25% 0% / 75% 40px,
vline to calc(100% - 20px),
curve to 0% calc(100% - 20px)
with 75% 100% / 25% calc(100% - 40px),
close
);
}
添加自定义属性和动画
现在,形状已在 CSS 中定义,您还可以使用自定义属性来轻松操控高度:
.flag {
--wave-height: 40px;
clip-path: shape(
from 0px var(--wave-height),
curve to 100% var(--wave-height)
with 25% 0px / 75% calc(var(--wave-height) * 2),
vline to calc(100% - var(--wave-height)),
curve to 0 calc(100% - var(--wave-height))
with 75% 100% / 25% calc(100% - var(--wave-height) * 2),
close
)
}
您甚至可以使用 @property
描述符为 CSS 属性添加动画效果,并将其限制在合理范围内:
@property --animated-wave-height {
syntax: "<length>";
inherits: false;
initial-value: 40px;
}
@keyframes curve {
from { --animated-wave-height: 0px; }
to { --animated-wave-height: 180px; }
}
.flag {
width: 600px;
height: 400px;
background: green;
animation: curve 1s infinite alternate;
--wave-height: calc(min(var(--animated-wave-height, 40px), 40%));
clip-path: shape(
from 0px var(--wave-height),
curve to 100% var(--wave-height)
with 25% 0px / 75% calc(var(--wave-height) * 2),
vline to calc(100% - var(--wave-height)),
curve to 0 calc(100% - var(--wave-height))
with 75% 100% / 25% calc(100% - var(--wave-height) * 2),
close
)
}
试用演示
在 Chrome 135 或 Safari 18.4 中,您可以在此 CodePen 演示中看到使用 clip-path: shape()
创建的动画旗形。
摘要
借助 clip-path: shape()
,您可以使用任意自适应形状剪裁元素,而这之前只能使用圆锥渐变或 JavaScript 构建的 SVG 等技术实现。
如需查看完整的语法,请参阅规范。
目前,它仅适用于 clip-path
。我们希望未来能使用这种形状来设置元素边框的形状,从而解锁更多非矩形的表达方式。