Reputation: 653
I'd like to know if it's possible to start a non-looping GIF from the beginning with CSS animation? For my example I have two GIFs. The first counts 1,2,3 each second - the second GIF counts 4,5,6 each second.
My goal is to show the first GIF until it counts to 3, then switch to the second GIF until it counts to 6, where it stops. My issue is that the second GIF will always be on 6 if I get it to show, at all.
My setup is as follows:
<div id="gif-two" class="gif"></div>
<div id="gif-one" class="gif"></div>
CSS
.gif {
width: 300px;
height: 300px;
position: absolute;
top: 0;
left: 50%;
margin-left: -150px;
}
#gif-one {
background: url("http://i.imgur.com/jLTVHdY.gif");
}
#gif-two {
background: url("http://i.imgur.com/O61k5Nf.gif");
}
I'm at a loss on how to handle this at the moment. I've tried toggling visibility
- but have no idea how to make this work in just CSS.
Upvotes: 2
Views: 3305
Reputation: 89780
Note: It is possible to achieve what you want by using CSS animations (as you will see from this answer) but I'd recommend you to combine them into the same GIF and use it that way because the approach used in this answer is too complex (so much so that I may struggle to explain it).
When the GIF is added as abackground-image
, both images are loaded at pretty much same time by the browser and the GIF animation starts executing immediately. This means that change from 4-5 on the second GIF is happening at almost the same time as 1-2 on the first GIF. So, when the first GIF's loop ends, the second GIF's loop would also have ended and this is why you'd always see only 6.
The only way to avoid that from happening is to make the browser load the image after the first loop is completed. Below snippet achieves just this in a very complicated manner. The below is how:
opacity
change from 1 to 0 starts at 95%
itself to create a fade-out effect. Otherwise, at the end of loop it looks as though it blinks off and the second GIF blinks on (which doesn't look pleasing).100%
). This means that the second image is loaded only after 3s (duration) and it starts its loop only from that time (by which, the loop of the first is already completed)..gif {
width: 300px;
height: 300px;
position: absolute;
top: 0;
left: 50%;
margin-left: -150px;
}
#gif-one {
animation: img 3s linear forwards;
background: url(http://i.imgur.com/jLTVHdY.gif?3);
}
#gif-two {
animation: img2 3s linear forwards;
z-index: -1;
}
@keyframes img {
0%, 95% {
opacity: 1;
}
100% {
opacity: 0;
}
}
@keyframes img2 {
0%, 99% {
background-image: none;
}
100%{
background: url(http://i.imgur.com/O61k5Nf.gif?3);
}
}
<div id="gif-one" class="gif"></div>
<div id="gif-two" class="gif"></div>
Note: As I was writing this answer, I realized that setting the background-image
within @keyframes
rules does not work in IE and Firefox. Hence, the above solution is WebKit only. Also, as far as I am aware there is no other pure CSS solution possible. You would have to use JavaScript and that would help in the cache busting that CBroe is referring to also. Below is a sample demo using JS.
Using single element + JS:
window.onload = function() {
var el = document.querySelector('.gif');
el.style.backgroundImage = 'url(http://i.imgur.com/jLTVHdY.gif' + Math.random() + ')';
setTimeout(function() {
el.style.backgroundImage = 'url(http://i.imgur.com/O61k5Nf.gif' + Math.random() + ')';
}, 3250);
}
.gif {
width: 300px;
height: 300px;
position: absolute;
top: 0;
left: 50%;
margin-left: -150px;
}
<div class="gif"></div>
Using two elements + JS:
window.onload = function() {
var el1 = document.querySelector('#gif-one'),
el2 = document.querySelector('#gif-two');
el1.style.backgroundImage = 'url(http://i.imgur.com/jLTVHdY.gif' + Math.random() + ')';
setTimeout(function() {
el1.style.opacity = '0';
el2.style.backgroundImage = 'url(http://i.imgur.com/O61k5Nf.gif' + Math.random() + ')';
}, 3250);
}
.gif {
width: 300px;
height: 300px;
position: absolute;
top: 0;
left: 50%;
margin-left: -150px;
transition: opacity .05s .5s;
}
<div id="gif-one" class="gif"></div>
<div id="gif-two" class="gif"></div>
Upvotes: 2