@keyframes内直接使用var(--x)会失效,因CSS动画规范禁止在其中解析变量;变量须定义在触发动画的元素上,并通过calc()间接引用,如transform: translateX(calc(var(--dist)))。

为什么@keyframes里直接写var(--x)会失效
不是浏览器bug,是CSS动画规范明确禁止:@keyframes块内不解析变量,所有var(--x)会被静默丢弃。你看到动画不动、位移卡死,大概率栽在这儿。
真正生效的路径只有一条:变量必须定义在触发动画的元素上(比如.path-item或:root),再通过animation属性本身或calc()间接引用——不能出现在@keyframes体内。
-
@keyframes move { 100% { transform: translateX(var(--dist)); } }→ ❌ 白写 -
@keyframes move { 100% { transform: translateX(calc(var(--dist))); } }→ ✅ 必须包calc() -
.path-item { --dist: 120px; animation: move 0.4s ease; }→ ✅ 变量在元素上才有效
offset-distance绑定变量必须用calc()包裹
直接写offset-distance: var(--dist)在Chrome/Safari里静默降级为0,Firefox直接忽略。规范要求该属性值必须带单位,而var()单独不参与计算上下文。
✅ 正确写法是强制走计算流程:offset-distance: calc(var(--dist) * 1%) 或 offset-distance: calc(var(--dist) * 1px),单位必须显式出现在calc()内部。
立即学习“前端免费学习笔记(深入)”;
- --dist存纯数字(如
35)→ 用calc(var(--dist) * 1%) - --dist存带单位值(如
35px)→ 可用calc(var(--dist)),但统一用无单位+显式单位更稳 - 别嵌套
calc(calc(var(--dist)) * 1%),Safari对多层calc()支持不稳定
stroke-dashoffset动画必须靠transition驱动
@keyframes里写stroke-dashoffset: var(--offset)无效——它只在CSS解析时取一次值。浏览器对自定义属性的动画支持,依赖的是transition触发重绘,不是帧插值。
✅ 唯一可靠路径:transition: stroke-dashoffset 0.4s ease,且变量值必须带单位(如--offset: 120),使用时补上:stroke-dashoffset: calc(var(--offset) * 1px)。
-
stroke-dasharray必须等于路径真实长度,硬编码100而实际长度是137.2,动画永远差一段 - 用JS获取:
const len = path.getTotalLength(),CSS中绑定:stroke-dasharray: calc(var(--len) * 1px) - 初始态设死:
stroke-dashoffset: calc(var(--len) * 1px),否则第一帧可能闪动
响应式缩放后路径长度必须重算
SVG有viewBox="0 0 100 100",渲染宽高是200px × 200px,缩放比为2,但getTotalLength()返回的是原始坐标系长度——变量若没同步乘以缩放比,动画就偏了。
resize后必须重新调用path.getTotalLength()并更新--len和--offset,否则变量值失准。
- 导出SVG时禁用“简化锚点”或“优化路径”,Figma/AI默认开启这些,容易插入冗余贝塞尔点导致
getTotalLength()异常 - 内联SVG才能读取父级变量;
<img src="icon.svg">完全隔离样式,currentColor和自定义属性都不可用 - 路径原始写了
fill="#000"属性,CSS的fill: var(--color)不会生效,必须删掉或改为fill="none"


















