Jonas Kohl
Jonas Kohl

Reputation: 1142

CSS animation infinite not working

I have the following code:

.dangerous_b {
    width: 636px;
    height: 72px;
    background-image: url('/media/anim.png');
    float: left;
    background-color: black;
    animation: bganim 100ms steps(1, start) infinite;
}
@keyframes bganim {
    from { background-position: 0px 0px; }
    to { background-position: 0px -72px; }
}

But the animation is only playing once. What am I doing wrong?


EDIT: Note that the animation plays out once, so there is a visual difference. But I want the animation to loop.

Btw: Here is the picture I used: https://i.sstatic.net/wJcCl.png


2nd EDIT: Here is the code snippet

.dangerous_b {
    width: 636px;
    height: 72px;
    background-image: url('https://i.sstatic.net/wJcCl.png');
    float: left;
    background-color: black;
    animation: bganim 100ms steps(1, start) infinite;
}
@keyframes bganim {
    from { background-position: 0px 0px; }
    to { background-position: 0px -72px; }
}
<div class="dangerous_b"></div>


3rd EDIT: It's working now with the following code:

.dangerous_b {
    width: 636px;
    height: 72px;
    background-image: url('https://i.sstatic.net/wJcCl.png');
    float: left;
    background-color: black;
    animation: bganim 100ms steps(1, start) infinite;
}
@keyframes bganim {
    50% { background-position: 0px -72px; }
}

Upvotes: 1

Views: 4628

Answers (2)

Harry
Harry

Reputation: 89750

Reason:

Problem is because of the animation-timing-function. A value of steps(1,start) means that the animation has only one step and it happens right at the start of the animation itself.

As per MDN (picked from definition for step-start but it is same as steps(1, start)):

Using this timing function, the animation jumps immediately to the end state and stay in that position until the end of the animation.

First step of the first iteration happens as soon as the page is loaded (or class is added) and due to it, the background image immediately moves to the position indicated inside the to frame. For the 2nd iteration, the move back to its original position (from frame) and then to the final position (to frame) again happens instantaneously meaning that you don't get to see any visual difference and it looks as though the element is staying at its place without any animation.

.dangerous_b {
  width: 636px;
  height: 72px;
  background-image: url('http://i.imgur.com/fA80qQc.png');
  float: left;
  background-color: black;
  animation: bganim 1s steps(1, start) infinite;
}
@keyframes bganim {
  from {
    background-position: 0px 0px;
  }
  to {
    background-position: 0px -72px;
  }
}
<div class='dangerous_b'></div>

The same behavior can be seen in this fiddle also. This is not my creation but is an adaptation of the demo present as designmodo. The first car never actually moves (or is never actually seen to move) because the step happens right at the start.


Solution 1: Use two steps and double the ending background position

When the no. of steps is set to two, the animation happens as a two step process where the first step again happens at the start of the animation (because of start parameter). This means:

  • During the first step, the background moves to half distance between the start and the end state.
  • Since 1st step happens right at the start, background-position is never 0px 0px. (Do note that, I have doubled the end background-position).
  • In the 2nd step, the background moves to the final position. Because the background images are repeated, 0px -144px is equal to 0px 0px. This creates an illusion of the background moving to its original position.

.dangerous_b {
  width: 636px;
  height: 72px;
  background-image: url('http://i.imgur.com/fA80qQc.png');
  float: left;
  background-color: black;
  animation: bganim 1s steps(2, start) infinite;
}
@keyframes bganim {
  from {
    background-position: 0px 0px;
  }
  to {
    background-position: 0px -144px;
  }
}
<div class='dangerous_b'></div>


Solution 2: Use just one step but change the end position to half way

For some reason, this seems to mimic a two step animation.

  • In the first half, the background moves to the position indicated within 50% frame.
  • During second half, it seems to go back to the original position (or 100% position, both of which are the same). Thus when next iteration starts and the image jumps, it moves from 0% or 100% position to 50% position and ends up producing the required animation effect.

.dangerous_b {
  width: 636px;
  height: 72px;
  background-image: url('http://i.imgur.com/fA80qQc.png');
  float: left;
  background-color: black;
  animation: bganim 1s steps(1, start) infinite;
}
@keyframes bganim {
  0% {
    background-position: 0px 0px;
  }
  50% {
    background-position: 0px -72px;
  }
  100% {
    background-position: 0px 0px;
  }
}
<div class='dangerous_b'></div>

Upvotes: 5

Pimmol
Pimmol

Reputation: 1871

If I understand it correctly, it now takes 1 frame to run your animation. Since your background image is moving out of sight, you won't see it.

https://developer.mozilla.org/nl/docs/Web/CSS/timing-function#The_steps()_class_of_timing-functions

Upvotes: 0

Related Questions