25

I want to fade between images in a loop (like result here-jsfiddle.net/5M2PD) but purely through CSS, no JavaScript. I tried using key-frames but I wasn't successful. Please Help.

@keyframes cf3FadeInOut {
    0% {
        opacity:1;
    }
    45% {
        opacity:1;
    }
    55% {
        opacity:0;
    }
    100% {
        opacity:0;
    }
}

#cf3 img.top {
   animation-name: cf3FadeInOut;
   animation-timing-function: ease-in-out;
   animation-iteration-count: infinite;
   animation-duration: 10s;
   animation-direction: alternate;
}
Maciej A. Czyzewski
  • 1,539
  • 1
  • 13
  • 24
Rachit Sharma
  • 341
  • 1
  • 4
  • 14
  • Maybe an interesting idea for the future, but I don't think most current browsers will like @keyframes - even more because most people don't use the latest versions. – MightyPork Jul 30 '13 at 19:05
  • Thank you MightyPork for the suggestion. Is there any other alternative? for CSS only? – Rachit Sharma Jul 30 '13 at 19:10
  • I don't think so.. personally, I'd stick to JS, but if that's not an option, I don't know. – MightyPork Jul 30 '13 at 19:11
  • animation is still prefixed in most browsers (-webkit-animation, -webkit-keyframes), which could be part of your problem. To clarify, you're going to apply top to the next image, and then you want that one to fade in? You could use transition for that, instead of animation. – Zachary Olson Jul 30 '13 at 19:38
  • there's a helpful post on how to do this here: https://www.devtwins.com/blog/css-cross-fading-images – Zach White Dec 14 '21 at 18:27

4 Answers4

39

I have taken your fiddle as a base, and made it work without script.

updated demo

I needed to set an id to the HTML

.fadein img {
    position:absolute;
    top:0;
    -webkit-animation-name: fade;
    -webkit-animation-iteration-count: infinite;
    -webkit-animation-duration: 6s;
    animation-name: fade;
    animation-iteration-count: infinite;
    animation-duration: 6s;
}

@-webkit-keyframes fade {
    0% {opacity: 0;}
    20% {opacity: 1;}
    33% {opacity: 1;}
    53% {opacity: 0;}
    100% {opacity: 0;}
}
@keyframes fade {
    0% {opacity: 0;}
    20% {opacity: 1;}
    33% {opacity: 1;}
    53% {opacity: 0;}
    100% {opacity: 0;}
}

#f1 {
    background-color: lightblue;
}
#f2 {
    -webkit-animation-delay: -4s;
    background-color: yellow;
}
#f3 {
    -webkit-animation-delay: -2s;
    background-color: lightgreen;
}
<div class="fadein">
    <img id="f3" src="http://i.imgur.com/R7A9JXc.png">
    <img id="f2" src="http://i.imgur.com/D5yaJeW.png">
    <img id="f1" src="http://i.imgur.com/EUqZ1Er.png">
</div>

I am setting the keyframes to give aprox 1/3 of the time visible, with apropiate transitions. Then I set different delays for every image, so that they alternate. If you want full browser support, you will need more vendor prefixes. I have used -webkit- and bare property so that you get the idea.

vals
  • 61,425
  • 11
  • 89
  • 138
  • 1
    Nice! How can I set up this for only two images? I can't find out, I have tried to remove `` from the markup and `#f3 { -webkit-animation-delay: -2s; background-color: lightgreen; }` from the CSS code. But it does not work. – candlejack Mar 20 '17 at 15:06
  • 2
    @alessadro the keyframes change opacity at 33% because there are 3 elements. You need to change this to 50% to adjust for 2 elements – vals Mar 20 '17 at 20:14
  • 1
    @candlejack For 2 elements instead of 3, remove all mentions of `f3` as you have done already, and change the `-webkit-animation-delay` on `#f2` to -2s. Finally, change the `-webkit-animation-duration` (and `animation-duration`) to 4s. – Jamie Birch Jun 06 '17 at 22:17
  • 1
    Working great on latest Chrome, Firefox, Edge browsers. – BobC Apr 25 '19 at 00:04
  • can use nth-of-type over #f1 nowadays http://jsfiddle.net/4d1uwj5f/ – Lawrence Cherone Dec 27 '19 at 10:53
  • It would be great if this wasn't so much dependent on the number of frames. Please check this: https://stackoverflow.com/questions/58803373/making-a-proper-fade-in-and-fade-out-for-a-slideshow/64064866#64064866 – Luis A. Florit Sep 25 '20 at 13:15
3

I've made a dynamic solution with SASS. It's possible to configure:

  • Total animation time
  • Amount of items
  • Transition speed

It automatically calculates the keyframe percentages and delays between items.

Codepen.io demo

// Demo styles
.fadecycle div {
  opacity: 0;
  position: absolute;
  width: 200px;
  line-height: 200px;
  text-align: center;
}

.fadecycle div:nth-child(1) { background: lightsalmon; }
.fadecycle div:nth-child(2) { background: lightsteelblue; }
.fadecycle div:nth-child(3) { background: lightseagreen; }
.fadecycle div:nth-child(4) { background: lightskyblue; }

// Animation settings
$totalTime: 8s;
$items: 4;
$transitionSpeed: 1.5;

// Calculate transition + display time in seconds
$transitionTime: 0s + $totalTime / ($items * $transitionSpeed * 2);
$displayTime: (0s + $totalTime - ($transitionTime * $items)) / $items;

// Set transition for each element
@for $i from 1 through $items {
  .fadecycle div:nth-child(#{$i}) {
    // Delay is increased for each item
    // starting with an offset of -$transitionTime so the first element is displayed on load
    $delay: -$transitionTime + ($transitionTime + $displayTime) * ($i - 1);
    animation: fadeinout $totalTime linear $delay infinite;
  }
}

// Calculate percentages of the times for keyframes
$transitionPercentage: 0% + 100 * ($transitionTime / $totalTime);
$displayPercentage: 0% + 100 * ($displayTime / $totalTime);

@keyframes fadeinout {
  0% {
    opacity: 0;
  }
  #{$transitionPercentage},
  #{$transitionPercentage + $displayPercentage} {
    opacity: 1;
  }
  #{$transitionPercentage + $displayPercentage + $transitionPercentage},
  100% {
    opacity: 0;
  }
}

Andreas Furster
  • 1,558
  • 1
  • 12
  • 28
0

Depending on how many images you want, how long you want each image to display, and how long you want the fade transition to last, you will need different values for your keyframes each time. A helpful post on how to do it properly each time can be found here: https://www.devtwins.com/blog/css-cross-fading-images

Zach White
  • 161
  • 1
  • 7
0

Here is another site to teach cross fading image , both time based and event based, with relatively small CSS:

http://css3.bradshawenterprises.com/cfimg/

pref
  • 1,651
  • 14
  • 24