动画不适用于计算的 CSS 变量

问题描述

我想使用 CSS var 为 SVG 圆的属性 stroke-dasharray 设置动画。

绿色表示动画正确且动画连续流畅
红色表示动画不正确,因为它按步骤制作动画。

我认为计算的 CSS 变量有问题,但我不明白是什么。
我们可以看到带有正方形的动画即使使用了计算的 CSS 变量也是正确的。

body {
  display: flex;
}

svg {
  width: 200px;
  height: 200px;
}

circle.good {
  stroke: green;
  stroke-width: 5;
  animation: good-dash 2s ease-in-out infinite;
}

circle.bad {
  stroke: red;
  stroke-width: 5;
  animation: bad-dash 2s ease-in-out infinite;
  --stroke-dasharray: 10;
}

.square {
  width: 200px;
  height: 200px;
  background-color: green;
  animation: good-roll 2s infinite ease-in-out both;
  position: relative;
  --left: 1;
}

@keyframes good-dash {
  0% {
    stroke-dasharray: 1,10;
  }
  50% {
    stroke-dasharray: 1,5;
  }
  100% {
    stroke-dasharray: 1,10;
  }
}

@keyframes bad-dash {
  0% {
    stroke-dasharray: 1,var(--stroke-dasharray);
  }
  50% {
    stroke-dasharray: 1,calc(var(--stroke-dasharray) / 2);
  }
  100% {
    stroke-dasharray: 1,var(--stroke-dasharray);
  }
}

@keyframes good-roll {
  0% {
    left: calc(var(--left) * 1px);
  }
  50% {
    left: calc(var(--left) * 50px);
  }
  100% {
    left: calc(var(--left) * 1px);
  }
}
<svg viewBox="25 25 50 50">
  <circle class="good" cx="50" cy="50" r="20" fill="none"/>
</svg>
<svg viewBox="25 25 50 50">
  <circle class="bad" cx="50" cy="50" r="20" fill="none"/>
</svg>
<div class="square"></div>

解决方法

在涉及并非自然无单位的东西的 calc 表达式中单位是强制性的,实际上您应该尝试在任何地方使用它们,因为 CSS 主要需要它们。

  • opacity 是一个真正无单位的属性,它只是一个 <number> in the specification

  • stroke-dasharray 然而不是无单位的,它要么是一个 <length> 要么是一个 <percentage>

  • SVG 有一个特殊的“遗留”规则,即 SVG 特有的一些通常需要单位的属性可以不用单位编写。

当涉及到 calc 表达式时,虽然允许省略单位的特定 SVG 规则不适用并且 everything that should have a unit,must have a unit。 Chrome 目前尚未实施此要求,但我预计他们会在某个时候实施。

body {
  display: flex;
}

svg {
  width: 200px;
  height: 200px;
}

circle.good {
  stroke: green;
  stroke-width: 5;
  animation: good-dash 2s ease-in-out infinite;
}

circle.bad {
  stroke: red;
  stroke-width: 5;
  animation: bad-dash 2s ease-in-out infinite;
  --stroke-dasharray: 10px;
}

.square {
  width: 200px;
  height: 200px;
  background-color: green;
  animation: good-roll 2s infinite ease-in-out both;
  position: relative;
  --left: 1;
}

@keyframes good-dash {
  0% {
    stroke-dasharray: 1,10;
  }
  50% {
    stroke-dasharray: 1,5;
  }
  100% {
    stroke-dasharray: 1,10;
  }
}

@keyframes bad-dash {
  0% {
    stroke-dasharray: 1px,var(--stroke-dasharray);
  }
  50% {
    stroke-dasharray: 1px,calc(var(--stroke-dasharray) / 2);
  }
  100% {
    stroke-dasharray: 1px,var(--stroke-dasharray);
  }
}

@keyframes good-roll {
  0% {
    left: calc(var(--left) * 1px);
  }
  50% {
    left: calc(var(--left) * 50px);
  }
  100% {
    left: calc(var(--left) * 1px);
  }
}
<svg viewBox="25 25 50 50">
  <circle class="good" cx="50" cy="50" r="20" fill="none"/>
</svg>
<svg viewBox="25 25 50 50">
  <circle class="bad" cx="50" cy="50" r="20" fill="none"/>
</svg>
<div class="square"></div>

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...