I have a fiddle (Fiddle A) in which cross-fade gallery of images happen for 2 images (2 tiles). Here is the snippets of html/css which I have used.
<div class="featured-block" style="display:flex; justify-content: center;">
<a href="https://www.google.com/" class="featured-block__item cf">
<div class="featured-block__item-inner">
<figure class="featured-block__image img-fit" itemprop="image" itemscope="" itemtype="http://schema.org/ImageObject">
<img class="default-opacity" src="https://i.imgur.com/EUqZ1Er.png" data-fallback-img="https://i.imgur.com/EUqZ1Er.png" alt="Outburst">
</figure>
</div>
</a>
</div>
Here are the @keyframes which I have used 2 images (2 tiles) for the above html:
@keyframes cf4FadeInOut {
0% {
opacity: 0;
}
20% {
opacity: 1;
z-index: 999;
}
33% {
opacity: 1;
}
53% {
opacity: 0;
z-index: 1;
}
100% {
opacity: 0;
}
}
The above css-animation in Fiddle A is working perfectly fine(which is exactly what I want) when there are 2 tiles (2 images).
Problem Statement:
The above fiddle (Fiddle A) is working perfectly fine for 2 images. I want the same css-animation/cross-fade gallery of images happens when there 3 and 4 images.
Here is the fiddle for 4 images(4 tiles) https://jsfiddle.net/zwjt8qko/1/embedded/result (Fiddle B)
Here is the fiddle for 3 images(3 tiles) https://jsfiddle.net/f6gr7kL1/embedded/result (Fiddle C)
I am wondering what changes I should make in the keyframes in the Fiddle B (4 images) and Fiddle C (3 images) above so that the same css-animation/cross-fade happens which is happening in Fiddle A right now.
I am open to a JavaScript solution as well.
Basic approach:
opacity: 0
.1
.animation-duration
like you'd have to with keyframes.const pics = document.querySelectorAll('.pic');
const lastPic = pics.length - 1;
const transitionDuration = 800; // matches CSS
const transitionDelay = 3000; // up to you
const totalDelay = transitionDuration + transitionDelay;
const intervalDelay = (transitionDuration * 2) + transitionDelay; // time to fade out + time to fade in + time to stay active
function toggleClass() {
const activePic = document.querySelector('.pic.active');
const activeIndex = Array.prototype.indexOf.call(pics, activePic);
const nextIndex = activeIndex === lastPic ? 0 : activeIndex + 1;
const nextPic = pics[nextIndex];
setTimeout(() => activePic.classList.remove('active'), transitionDelay);
setTimeout(() => nextPic.classList.add('active'), totalDelay);
}
setInterval(toggleClass, intervalDelay);
.wrapper {
width: 400px;
height: 300px;
position: relative;
}
.pic {
position: absolute;
top: 0;
left: 0;
width: 100%;
opacity: 0;
transition: opacity 800ms ease; /* immediately start fading out when active class is lost */
}
.pic.active {
opacity: 1;
}
<div class="wrapper">
<img class="pic active" src="https://via.placeholder.com/400x300?text=picture%201" alt="">
<img class="pic" src="https://via.placeholder.com/400x300?text=picture%202" alt="">
<img class="pic" src="https://via.placeholder.com/400x300?text=picture%203" alt="">
<img class="pic" src="https://via.placeholder.com/400x300?text=picture%204" alt="">
</div>
I won't go into full detail here, but it would probably look something like this:
@keyframes pulse1 {
0% {
opacity: 1;
}
20% {
opacity: 0;
}
}
@keyframes pulse2 {
0% {
opacity: 0;
}
25% {
opacity: 1;
}
45% {
opacity: 0;
}
}
@keyframes pulse3 {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
70% {
opacity: 0;
}
}
@keyframes pulse4 {
0% {
opacity: 0;
}
75% {
opacity: 1;
}
}
Note that we don't even toggle the z-index
because there's no point: only one of them is ever visible at a time. Just position them all on top of each other from the start, and their z-index
won't matter.
(I don't think the z-index
portion of the animation you have in your question is even doing anything because z-index
isn't animatable.)