16

I have a list of boxes with a background image that scrolls vertically with:

@keyframes movie {
   0% { background-position: 50% 5%; }
   50% { background-position: 50% 95%; }
   0% { background-position: 50% 5%; }
}

.movie {
    animation: movie 50s linear infinite;
}

The "problem" is that in this way all the boxes have the background moving at the same time.
I'd like to have a "random start point" so that each box has a different animation.

For example, one background is moving down while another is moving up.

It is possible with pure CSS? I can't find a simple way neither with Javascript..

4 Answers 4

28

You can use negative animation delay.

https://developer.mozilla.org/en-US/docs/Web/CSS/animation-delay

Specifying a negative value for the animation delay causes the animation to begin executing immediately. However, it will appear to have begun executing partway through its cycle. For example, if you specify -1s as the animation delay time, the animation will begin immediately but will start 1 second into the animation sequence.

So if you want your animation start at 20%, animation delay would be ( -50s * 20% ). You just need to use javascript to create random start point.

Sign up to request clarification or add additional context in comments.

Comments

9

You can use animation-delay.

animation-delay: 10s;

Or inside your shorthand:

animation: movie 50s linear 10s infinite;

Maybe easier to handle, with some pseudo-classes:

.movie:nth-of-type(1) {
  animation-delay: 10s;
}

.movie:nth-of-type(2) {
  animation-delay: 20s;
}

.movie:nth-of-type(3) {
  animation-delay: 30s;
}

1 Comment

Thanks but in this way the animation will start with a delay, not on a different start point.
5

To elaborate on the suggestion in Chef's answer, the Javascript to randomise the animation delays on a bunch of elements might look something like this:

var elements = document.querySelectorAll('.movie')
var animationDuration = 50000; // in milliseconds

// Set the animationDelay of each element to a random value
// between 0 and animationDuration:
for (var i = 0; i < elements.length; i++) {
  var randomDuration = Math.floor(Math.random() * animationDuration);
  elements[i].style.animationDelay = randomDuration + 'ms';  
}

Of course, you can multiply randomDuration by -1 if you want to use negative values for animation delay (so some elements start mid-animation rather than having their initial animation delayed).

Comments

5

This can be done with pure CSS, without writing (or generating via SCSS etc), using a combination of:

  • A negative animation-delay to change the start time of the animation
  • Multiple nth-child or nth-of-type rules to apply formulas that will 'randomize' rule application
movie.nth-child(2n) { animation-delay: -10s }  
movie.nth-child(2n+1) { animation-delay: -30s }  
movie.nth-child(3n) { animation-delay: -20s; }  
movie.nth-child(5n) { animation-delay: -40s }  
movie.nth-child(7n) { animation-delay: -15s }  
{etc}

Using just the first 2 rules gives alternating rules (e.g. even/odd rows in a table). Notice the second rule which has a +1 offset - this is important if your class (movie) doesn't have an appropriate default for the rule you are changing (0 by default anyways for animation-delay).

Using nth-child(n) formulas with prime multiples of n makes an effective pattern length equal to the product of all your prime factors (e.g. 2*3*5*7 = 210 elements before repeating).

li {
  animation: movie 1s linear infinite;
}
@keyframes movie {
  20% { color: white }
  40% { color: black }
}
li:nth-child(2n-1) {
  background-color: lime;
  animation-delay: .1s;
}
li:nth-child(2n) {
  background-color: orange;
  animation-delay: -.2s;
}
li:nth-child(3n) {
  background-color: yellow;
  animation-delay: .3s;
}
li:nth-child(5n) {
  background-color: magenta;
  animation-delay: -.5s;
}
li:nth-child(7n) {
  background-color: aqua;
}
<ul>
  <li>0</li>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
  <li>6</li>
  <li>7</li>
  <li>8</li>
  <li>9</li>
  <li>10</li>
  <li>11</li>
  <li>12</li>
  <li>13</li>
</ul>

For further randomization, you could create a second set of rules with slightly different n multiples/offsets and change the animation-duration (or any other rule really).

1 Comment

One could also base the animation delay value(s) on a CSS variable, and update that base value randomly from JS for a more dynamic effect. See css-tricks.com/random-numbers-css

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.