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.
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.
/*
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>
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?
Rendering the same result:
Windows 10 / 64-bit
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.
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).
The animation-play-state CSS property sets whether an animation is running or paused.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With