[css] Changing Background Image with CSS3 Animations

Why this isn't working? What am I doing wrong?

CSS

@-webkit-keyframes test {
  0% {
    background-image: url('frame-01.png');
  }
  20% {
    background-image: url('frame-02.png');
  }
  40% {
    background-image: url('frame-03.png');
  }
  60% {
    background-image: url('frame-04.png');
  }
  80% {
    background-image: url('frame-05.png');
  }
  100% {
    background-image: url('frame-06.png');
  }
}

div {
  float: left;
  width: 200px;
  height: 200px;
  -webkit-animation-name: test;
  -webkit-animation-duration: 10s;
  -webkit-animation-iteration-count: 2;
  -webkit-animation-direction: alternate;
  -webkit-animation-timing-function: linear;
}

DEMO

http://jsfiddle.net/hAGKv/

Thanks in advance!

This question is related to css background-image css-animations

The answer is


You can follow by this code:

_x000D_
_x000D_
#cd{_x000D_
  position: relative;_x000D_
  margin: 0 auto;_x000D_
  height: 281px;_x000D_
  width: 450px;_x000D_
}_x000D_
#cf img{_x000D_
  left: 0;_x000D_
  position: absolute;_x000D_
  -moz-transition: opacity 1s ease-in-out;_x000D_
  transition: opacity 1s ease-in-out;_x000D_
}_x000D_
#cf img.top:hover{_x000D_
  opacity: 0;_x000D_
}
_x000D_
<div id="cf">_x000D_
  <img class="button" src="Birdman.jpg" />_x000D_
  <img src="Turtle.jpg" class="top" />_x000D_
</div>
_x000D_
_x000D_
_x000D_


The linear timing function will animate the defined properties linearly. For the background-image it seems to have this fade/resize effect while changing the frames of you animation (not sure if it is standard behavior, I would go with @Chukie B's approach).

If you use the steps function, it will animate discretely. See the timing function documentation on MDN for more detail. For you case, do like this:

-webkit-animation-timing-function: steps(1,end);
animation-timing-function: steps(1,end);

See this jsFiddle.

I'm not sure if it is standard behavior either, but when you say that there will be only one step, it allows you to change the starting point in the @keyframes section. This way you can define each frame of you animation.


You can use the jquery-backstretch image which allows for animated slideshows as your background-images!

https://github.com/jquery-backstretch/jquery-backstretch Scroll down to setup and all of the documentation is there.


I needed to do the same thing as you and landed on your question. I ended up taking finding about the steps function which I read about from here.

JSFiddle of my solution in action (Note it currently works in Firefox, I'll let you add the crossbrowser lines, trying to keep the solution clean of clutter)

First I created a sprite sheet that had two frames. Then I created the div and put that as the background, but my div is only the size of my sprite (100px).

<div id="cyclist"></div>

#cyclist {
    animation: cyclist 1s infinite steps(2);
    display: block;
    width: 100px;
    height: 100px;
    background-image: url('../images/cyclist-test.png');
    background-repeat: no-repeat;
    background-position: top left;
  }

The animation is set to have 2 steps and have the whole process take 1 second.

@keyframes cyclist {
  0% {
    background-position: 0 0; 
   }
  100% { 
    background-position: 0 -202px; //this should be cleaned up, my sprite sheet is 202px by accident, it should be 200px
   }
}

Thiago above mentioned the steps function but I thought I'd elaborate more on it. Pretty simple and awesome stuff.


Like the above stated, you can't change the background images in the animation. I've found the best solution to be to put your images into one sprite sheet, and then animate by changing the background position, but if you're building for mobile, your sprite sheets are limited to less than 1900x1900 px.


I needed to do the same thing recently. Here's a simple implementation

_x000D_
_x000D_
#wrapper { width:100%; height:100%; position:relative; }_x000D_
#wrapper img { position:absolute; top:0; left:0; width:100%; height:auto; display:block; }_x000D_
#wrapper .top { animation:fadeOut 2s ease-in-out; animation-fill-mode:forwards; }_x000D_
@keyframes fadeOut {_x000D_
  0% { opacity:1; }_x000D_
  100% { opacity:0; }_x000D_
}
_x000D_
<div id="wrapper">_x000D_
  <img src="img1.jpg" class="top" style="z-index:2;">_x000D_
  <img src="img2.jpg" style="z-index:1;">_x000D_
</div>
_x000D_
_x000D_
_x000D_


You can use animated background-position property and sprite image.


This is really fast and dirty, but it gets the job done: jsFiddle

    #img1, #img2, #img3, #img4 {
    width:100%;
    height:100%;
    position:fixed;
    z-index:-1;
    animation-name: test;
    animation-duration: 5s;
    opacity:0;
}
#img2 {
    animation-delay:5s;
    -webkit-animation-delay:5s
}
#img3 {
    animation-delay:10s;
    -webkit-animation-delay:10s
}
#img4 {
    animation-delay:15s;
    -webkit-animation-delay:15s
}

@-webkit-keyframes test {
    0% {
        opacity: 0;
    }
    50% {
        opacity: 1;
    }
    100% {
    }
}
@keyframes test {
    0% {
        opacity: 0;
    }
    50% {
        opacity: 1;
    }
    100% {
    }
}

I'm working on something similar for my site using jQuery, but the transition is triggered when the user scrolls down the page - jsFiddle


Updated for 2020: Yes, it can be done! Here's how.

Snippet demo:

_x000D_
_x000D_
#mydiv{ animation: changeBg 1s infinite; width:143px; height:100px; }
@keyframes changeBg{
   0%,100%  {background-image: url("https://i.stack.imgur.com/YdrqG.png");}
   25% {background-image: url("https://i.stack.imgur.com/2wKWi.png");}
   50% {background-image: url("https://i.stack.imgur.com/HobHO.png");}
   75% {background-image: url("https://i.stack.imgur.com/3hiHO.png");}
}
_x000D_
<div id='mydiv'></div>
_x000D_
_x000D_
_x000D_


Background image [isn't a property that can be animated][1] - you can't tween the property.

Original Answer: (still a good alternative) Instead, try laying out all the images on top of each other using position:absolute, then animate the opacity of all of them to 0 except the one you want repeatedly.


Well I can change them in chrome. Its simple and works fine in Chrome using -webkit css properties.


Works for me. Notice the use of background-image for transition.

#poster-img {
  background-repeat: no-repeat;
  background-position: center;
  position: absolute;
  overflow: hidden;
  -webkit-transition: background-image 1s ease-in-out;
  transition: background-image 1s ease-in-out;
}

It works in Chrome 19.0.1084.41 beta!

So at some point in the future, keyframes could really be... frames!

You are living in the future ;)


Your code can work well with some adaptations :

div {
  background-position: 50% 100%;
  background-repeat: no-repeat;
  background-size: contain;
  animation: animateSectionBackground infinite 240s;
}

@keyframes animateSectionBackground {
  00%, 11% { background-image: url(/assets/images/bg-1.jpg); }
  12%, 24% { background-image: url(/assets/images/bg-2.jpg); }
  25%, 36% { background-image: url(/assets/images/bg-3.jpg); }
  37%, 49% { background-image: url(/assets/images/bg-4.jpg); }
  50%, 61% { background-image: url(/assets/images/bg-5.jpg); }
  62%, 74% { background-image: url(/assets/images/bg-6.jpg); }
  75%, 86% { background-image: url(/assets/images/bg-7.jpg); }
  87%, 99% { background-image: url(/assets/images/bg-8.jpg); }
}

Here is the explanation of the percentage to suit your situation:

First you need to calculate the "chunks". If you had 8 differents background, you need to do : 100% / 8 = 12.5% (to simplify you can let fall the decimals) => 12%

After that you obtain that :

@keyframes animateSectionBackground {
  00% { background-image: url(/assets/images/bg-1.jpg); }
  12% { background-image: url(/assets/images/bg-2.jpg); }
  25% { background-image: url(/assets/images/bg-3.jpg); }
  37% { background-image: url(/assets/images/bg-4.jpg); }
  50% { background-image: url(/assets/images/bg-5.jpg); }
  62% { background-image: url(/assets/images/bg-6.jpg); }
  75% { background-image: url(/assets/images/bg-7.jpg); }
  87% { background-image: url(/assets/images/bg-8.jpg); }
}

If you execute this code, you will see the transition will be permanantly. If you want the backgrounds stay fixed while a moment, you can do like this :

@keyframes animateSectionBackground {
  00%, 11% { background-image: url(/assets/images/bg-1.jpg); }
  12%, 24% { background-image: url(/assets/images/bg-2.jpg); }
  25%, 36% { background-image: url(/assets/images/bg-3.jpg); }
  37%, 49% { background-image: url(/assets/images/bg-4.jpg); }
  50%, 61% { background-image: url(/assets/images/bg-5.jpg); }
  62%, 74% { background-image: url(/assets/images/bg-6.jpg); }
  75%, 86% { background-image: url(/assets/images/bg-7.jpg); }
  87%, 99% { background-image: url(/assets/images/bg-8.jpg); }
}

That mean you want :

  • bg-1 stay fixed from 00% to 11%
  • bg-2 stay fixed from 12% to 24%
  • etc

By putting 11%, the transtion duration will be 1% (12% - 11% = 1%). 1% of 240s (total duration) => 2.4 seconds.

You can adapt according to your needs.


Examples related to css

need to add a class to an element Using Lato fonts in my css (@font-face) Please help me convert this script to a simple image slider Why there is this "clear" class before footer? How to set width of mat-table column in angular? Center content vertically on Vuetify bootstrap 4 file input doesn't show the file name Bootstrap 4: responsive sidebar menu to top navbar Stylesheet not loaded because of MIME-type Force flex item to span full row width

Examples related to background-image

How to add a color overlay to a background image? CSS: stretching background image to 100% width and height of screen? CSS blur on background image but not on content Adding background image to div using CSS How to apply a CSS filter to a background image How to use responsive background image in css3 in bootstrap Responsive background image in div full width Overlay a background-image with an rgba background-color Is there a way to set background-image as a base64 encoded image? Using HTML data-attribute to set CSS background-image url

Examples related to css-animations

How to window.scrollTo() with a smooth effect CSS smooth bounce animation Pure CSS animation visibility with delay Play multiple CSS animations at the same time Changing :hover to touch/click for mobile devices How can I create a marquee effect? How to make blinking/flashing text with CSS 3 CSS3 Spin Animation Blurry text after using CSS transform: scale(); in Chrome Imitating a blink tag with CSS3 animations