clip-path动画必须用css变量,因浏览器不支持polygon()函数值插值;需4个变量控制四顶点坐标,如--tl-x、--tl-y、--br-x、--br-y,并统一单位、声明transition、设置overflow:hidden。

clip-path 动画为什么必须用 CSS 变量
直接在 transition 里写 clip-path: polygon(...) 是无效的——浏览器不支持对 polygon() 这类函数值做插值动画。只有当起点和终点都是同一语法结构、且参数可逐项映射时,CSS 才能平滑过渡。CSS 变量(--x, --y)把数值抽离成可被 transition 跟踪的“标量”,再通过 calc() 注入到 polygon() 中,就绕过了语法不可动画的限制。
关键点:变量本身不能带单位或函数,只存纯数字;所有单位和函数结构必须写死在 clip-path 声明里。
全屏转场需要哪几个变量
一个基础的“中心缩放”全屏切换,最少需 4 个变量控制裁剪区域的四个顶点。例如从全屏 → 黑色圆形遮罩 → 新页面全屏,实际是两段 clip-path 变化:第一段收束到中心小圆,第二段从小圆展开。但更常用的是矩形渐变裁剪,用以下变量即可:
-
--tl-x:左上角横坐标(% 或 vw/vh 单位,推荐用vw避免响应式偏移) -
--tl-y:左上角纵坐标 -
--br-x:右下角横坐标 -
--br-y:右下角纵坐标
对应 clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%) 的默认全屏状态,只需把这四个点替换成变量:clip-path: polygon(var(--tl-x) var(--tl-y), var(--br-x) var(--tl-y), var(--br-x) var(--br-y), var(--tl-x) var(--br-y))。
transition 不生效的三个常见原因
即使变量设对了,动画仍可能卡住或跳变。排查优先级如下:
- 没给
clip-path所在元素加transition: clip-path 0.4s ease—— 注意不是transition: all,部分浏览器对all里的clip-path不触发硬件加速 - 变量初始值与目标值单位不一致,比如
--tl-x: 0vs--tl-x: 50vw,会导致插值失败,统一用vw或% - 父容器没设
overflow: hidden,导致裁剪区域外的内容溢出,视觉上像“没裁”
示例修复:
section {
clip-path: polygon(var(--tl-x) var(--tl-y), var(--br-x) var(--tl-y), var(--br-x) var(--br-y), var(--tl-x) var(--br-y));
transition: clip-path 0.5s cubic-bezier(0.33, 1, 0.68, 1);
overflow: hidden;
}
如何用 JS 切换变量实现页面转场
不要操作 style 内联样式去改每个变量,而是切换预设的 CSS 类,让变量批量更新。在 :root 或组件作用域里定义两套值:
:root {
--tl-x: 0vw;
--tl-y: 0vh;
--br-x: 100vw;
--br-y: 100vh;
}
:root.page-exit {
--tl-x: 50vw;
--tl-y: 50vh;
--br-x: 50vw;
--br-y: 50vh;
}
JS 只需:
document.documentElement.classList.add('page-exit');
// 等 transitionend 后跳转或加载新内容
element.addEventListener('transitionend', () => {
// 加载新页或重置变量
}, { once: true });
注意:如果页面高度动态变化,vh 在 iOS Safari 中会因地址栏显隐跳变,此时应改用 100% + 父容器 height: 100vh 锁定,或用 JS 监听 resize 动态更新 --vh 变量。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











