Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to remove a property from the `0%` keyframe of a CSS animation if it is already declared in the class the animation is applied to?

Context:

According to the Animation Spec:

If a ‘0%’ or ‘from’ keyframe is not specified, then the user agent constructs a ‘0%’ keyframe using the computed values of the properties being animated. If a ‘100%’ or ‘to’ keyframe is not specified, then the user agent constructs a ‘100%’ keyframe using the computed values of the properties being animated.

This can lead to two different interpretations:

  • A) Declare the property in the class and not in the 0% or from keyframe.

  • B) Declare the property in the class and in the 0% or from keyframe.


Simplified Example:

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;
  }
}
<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>

While both have the same end result, following the Don't Repeat Yourself (DRY) principle, A) could vastly reduce code for all the animations that use more than one property.


Complex Example:

/*
   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);
  }
}
<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>

Question:

Is it safe to remove a property from the 0% keyframe of a CSS animation if it is already declared in the class the animation is applied to?

Is doing this:

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

@keyframes example {
  100% {
    opacity: 1;
  }
}

considered safe across browsers? Or is it to be expected that user agents render different results or performance?


TESTS:

Rendering the same result:

Windows 10 / 64-bit

  • Chrome 54.0.2840.71 m (64-bit)
  • FireFox 49.0.2
  • Edge 25.10586.0.0
like image 253
Ricky Avatar asked Nov 01 '16 19:11

Ricky


People also ask

Which CSS animation property specifies the time it should take for the animation to complete?

The animation-delay CSS property specifies the amount of time to wait from applying the animation to an element before beginning to perform the animation. The animation can start later, immediately from its beginning, or immediately and partway through the animation.

Which property can help me if I want to start my animation after a few seconds?

The animation-delay property specifies a delay for the start of an animation. The animation-delay value is defined in seconds (s) or milliseconds (ms).

Which CSS property is used to play animation again and again?

The animation-play-state CSS property sets whether an animation is running or paused.

How does keyframe animation work CSS?

Each keyframe describes how the animated element should render at a given time during the animation sequence. Since the timing of the animation is defined in the CSS style that configures the animation, keyframes use a <percentage> to indicate the time during the animation sequence at which they take place.


2 Answers

The computed value of a property can vary depending on what CSS rules are applying to a given element, the specificity of these rules, whether the element has an inline style declaration for that property, whether a script is modifying the value of that property at runtime, etc.

If you want an animation to start from a predictable, and fixed, value, you will need to specify this value in the 0% keyframe so that it doesn't start animating from what the computed value happens to be at the time the animation starts instead.

You can leave out the 0% keyframe if you can guarantee that the computed value for that element at the time the animation is started is always a constant value. You must leave out the 0% keyframe if you want the animation to always start from whatever the computed value happens to be at the time, if it can change.

Similar rules apply to the 100% keyframe: if the animation needs to end with a fixed value regardless of what the computed value may be, you will need to specify the 100% keyframe; otherwise, if it needs to end with the same value as the computed value, you will need to leave it out.

like image 181
BoltClock Avatar answered Sep 25 '22 11:09

BoltClock


It can work in both way, as the specification point out.

Regarding safeness, this should be ok in the following browsers:

IE 11
Edge 14
Firefox from 47 to 52
Chrome  from 49 to 57
Safari  from 9.1 to 10

Keeping the 0% in my opinion could make your code more readable specially if you have complex animation, but in case you want avoid repetition you could use some CSS pre-processor, for example LESS using animation keyframes mixin or other techniques.

like image 39
GibboK Avatar answered Sep 26 '22 11:09

GibboK