如果已经在应用动画的类中声明了CSS动画的`0%`关键帧中的属性,是否安全?

Ric*_*cky 8 css css3 css-animations

语境:

根据动画规范:

如果未指定"0%"或"来自"关键帧,则用户代理使用要设置动画的属性的计算值构造"0%"关键帧.如果未指定"100%"或"到"关键帧,则用户代理使用要设置动画的属性的计算值构造"100%"关键帧.

这可能导致两种不同的解释:

  • A)在类中声明属性,而不是在0%或from关键帧中声明属性.

  • B)中声明的类的属性和在0%或from关键帧.


简化示例:

p:first-of-type {
  opacity: 0;
  animation: a 3s linear infinite alternate;
}
@keyframes a {
  100% {
    opacity: 1;
  }
}
p:last-of-type {
  opacity: 0;
  animation: b 3s linear infinite alternate;
}
@keyframes b {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
Run Code Online (Sandbox Code Playgroud)
<p>
  A) Declare the property in the class <strong>and not</strong> in the `0%` or `from` keyframe.
</p>
<p>
  B) Declare the property in the class <strong>and </strong> in the `0%` or `from` keyframe.
</p>
Run Code Online (Sandbox Code Playgroud)


虽然两者具有相同的最终结果,但遵循不要重复自己(DRY)原则, A)可以大大减少使用多个属性的所有动画的代码.


复杂的例子:

/*
   Layout
*/

* {
  box-sizing: border-box;
}
body {
  margin: 0;
}
ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
.container {
  height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  counter-reset: list-item;
}
.container > li {
  position: relative;
  counter-increment: list-item;
}
.container > li::before {
  content: counter(list-item, upper-alpha);
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: flex-end;
  align-items: flex-end;
  font-size: 1.5em;
  background-color: moccasin;
}
.container > li::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 0;
  width: 100%;
  transform: translateY(-50%);
  height: 2px;
  background-color: gold;
}
/*
  SVG
*/

.svg-spritesheet {
  display: none;
}
.svg__icon {
  display: inline-block;
  vertical-align: middle;
  width: 1em;
  height: 1em;
}
.svg__icon--square {
  font-size: 5em;
  color: dodgerblue;
}
/*
  Question Related
*/

.container > li:first-of-type .svg__icon--square {
  opacity: 0;
  transform: scale(.5) rotate(45deg);
  animation: animationA 5s linear infinite alternate;
}
.container > li:nth-child(2) .svg__icon--square {
  opacity: 0;
  transform: scale(.5) rotate(45deg);
  animation: animationB 5s linear infinite alternate;
}
@keyframes animationA {
  to {
    opacity: 1;
    transform: translateX(500px) scale(1) rotate(90deg);
  }
}
@keyframes animationB {
  from {
    opacity: 0;
    transform: scale(.5) rotate(45deg);
  }
  to {
    opacity: 1;
    transform: translateX(500px) scale(1) rotate(90deg);
  }
}
Run Code Online (Sandbox Code Playgroud)
<ul class="container">
  <li>
    <svg class="svg__icon svg__icon--square">
      <use xlink:href="#svg-icon-square"></use>
    </svg>
  </li>
  <li>
    <svg class="svg__icon svg__icon--square">
      <use xlink:href="#svg-icon-square"></use>
    </svg>
  </li>
</ul>

<svg class="svg-spritesheet">
  <symbol id="svg-icon-square" viewBox="0 0 32 32">
    <title>Demo Square</title>
    <rect width="32" height="32" fill="currentColor" />
  </symbol>
</svg>
Run Code Online (Sandbox Code Playgroud)


题:

0%如果已在应用动画的类中声明属性,那么从CSS动画的关键帧中删除属性是否安全?

这样做:

.el {
  opacity: 0;
  animation: example 1s;
}

@keyframes example {
  100% {
    opacity: 1;
  }
}
Run Code Online (Sandbox Code Playgroud)

跨浏览器安全吗?或者是否期望用户代理呈现不同的结果或性能?


测试:

渲染相同的结果:

Windows 10/64位

  • Chrome 54.0.2840.71米(64位)
  • FireFox 49.0.2
  • Edge 25.10586.0.0

Bol*_*ock 4

属性的计算值可能会有所不同,具体取决于应用于给定元素的 CSS 规则、这些规则的特殊性、该元素是否具有该属性的内联样式声明、脚本是否在运行时修改该属性的值, ETC。

如果您希望动画从可预测且固定的值开始,则需要在 0% 关键帧中指定该值,这样动画就不会从动画开始时计算出的值开始制作动画反而。

如果您可以保证动画启动时该元素的计算值始终是常量值,则可以省略 0% 关键帧。如果您希望动画始终从当时计算的值(如果可以更改)开始,则必须省略 0% 关键帧。

类似的规则适用于 100% 关键帧:如果动画需要以固定值结束,无论计算值是什么,您都需要指定 100% 关键帧;否则,如果它需要以与计算值相同的值结束,则需要将其省略。

  • @Ricky_Ruiz - 即使您知道某人的真实姓名,在 Stack Overflow 上称呼他们时,您也应该使用*他们*在这里使用的名字。 (3认同)