I have a list of boxes with a background image that scrolls vertically with:
@keyframes movie {
0% { background-position: 50% 5%; }
50% { background-positi
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;
}
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.
This can be done with pure CSS, without writing (or generating via SCSS etc), using a combination of:
animation-delay
to change the start time of the animationnth-child
or nth-of-type
rules to apply formulas that will 'randomize' rule applicationmovie.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 5s 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).
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).