Home > Net >  Hide & show 3 images on a loop using CSS
Hide & show 3 images on a loop using CSS

Time:01-18

Trying to loop through 3 images with only showing one at time for 7 seconds, which then disappears and then show the next one in the sequence, then the next image. The loop needs to be infinite without a "transition / fade" delay.

The images are animating GIFs, so trying to line up the timing with the transitions is so far failing to work.

Currently using this:

.images {
  margin: auto;
}

.images img {
  position: absolute;
  -webkit-animation: fade 21s infinite;
  animation: fade 21s infinite;
}

@keyframes fade {
  0% {
    opacity: 1;
  }
  15% {
    opacity: 1;
  }
  25% {
    opacity: 0;
  }
  90% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

-webkit-@keyframes fade {
  0% {
    opacity: 1;
  }
  15% {
    opacity: 1;
  }
  25% {
    opacity: 0;
  }
  90% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

#img1 {
  -webkit-animation-delay: 0s;
  animation-delay: 0s;
}

#img2 {
  -webkit-animation-delay: -7s;
  animation-delay: -7s;
}

#img3 {
  -webkit-animation-delay: -14s;
  animation-delay: -14s;
}
<div >
  <img id="img1" src="https://example.com/gif-1.gif">
  <img id="img2" src="https://example.com/gif-2.gif">
  <img id="img3" src="https://example.com/gif-3.gif">
</div>

Any help would be greatly appriciated

CodePudding user response:

Here you can define the duration in a variable to control the appearance time of a single image.

I'm using a single set of keyframes, changing the opacity of every image to 1 for ⅓ of the animation-duration (and to 0 for the remaining time).

Unfortunately calc can't be used to define percentages into keyframes, so if you change the number of images you also need to manually change those percentages, as described in the comments inside the code.

Grid display is used as an alternative of position: relative and position: absolute. fetchpriority was used for the first image to increase its priority (since it's the first image of the animation and it has to be loaded soon).

div {
   --time: 7s;
   display: grid;
}

img {   
 grid-area: 1/1;
 animation: rotate calc(var(--time) * 3) linear 0s infinite;
}

img:nth-child(2) { animation-delay: calc(var(--time) * -2); }
img:nth-child(3) { animation-delay: calc(var(--time) * -1); }


@keyframes rotate {
   /* 33.33% is (100% / number of images) */
   0%, 33.33% { opacity: 1; }
   /* 33.34% is (100% / number of images)   0.01 */
   33.34%, 100% { opacity: 0; }  
}
<div>
  <img src="https://picsum.photos/id/237/300/200/" fetchpriority="high" />
  <img src="https://picsum.photos/id/238/300/200/" />
  <img src="https://picsum.photos/id/239/300/200/" />
</div>

As a side note, for a matter of accessibility, you should give the user the capability to stop every animation longer than 5 seconds since it can potentially provoke seizures. In any case don't rotate images faster than 3 per second.

CodePudding user response:

It looks like you're using CSS animations to try to achieve the desired effect. However, there are a few issues with the current code that are preventing it from working as intended.

First, the animation-delay property is causing the images to be hidden for the entire 7 seconds before they are shown again. Instead, you should use the animation-duration property to control how long each image is visible for.

Second, the animation is currently set to fade in and out, which is not what you want. Instead, you should use the animation to control the visibility of the images by setting the opacity to 1 when the image should be visible and 0 when it should be hidden.

Finally, the looping is not working as intended because the animation is set to infinite but the duration is only 21s which is not divisible by 7s, so the loop will not align perfectly with the image change.

Here's an example of how you might modify your CSS to achieve the desired effect:

.images {
    margin:auto;
}

.images img {
    position:absolute;
    -webkit-animation: slide 21s infinite;
    animation: slide 21s infinite;
}

@keyframes slide {
    0% {
        opacity: 0;
    }
    14.28% {
        opacity: 1;
    }
    21.42% {
        opacity: 0;
    }
    100% {
        opacity: 0;
    }
}

-webkit-@keyframes slide {
    0% {
        opacity: 0;
    }
    14.28% {
        opacity: 1;
    }
    21.42% {
        opacity: 0;
    }
    100% {
        opacity: 0;
    }
}

It's also good to note that you could use JavaScript or Jquery to create this effect, it could be more efficient and also allow you to handle edge cases and make the looping more accurate.

  • Related