Treehouse

Multiple Background CSS Animations

By on  

CSS background animation has been a hot topic for a long time, mostly because they look pretty sweet and don't require additional elements.  I was recently asked if it was possible to have multiple background animations on a given element and the answer is yes...with concessions.  Let's take a look at how it's done!

The CSS

So multiple background images on an element is something we've been able to do for quite a while now, simply separate them with commas:

.animate-area	{ 
	background-image: url(twitter-logo-bird.png), url(treehouseFrog.png), url(bg-clouds.png);
	background-position: 20px -90px, 30px 80px, 0px 0px;
	background-repeat: no-repeat, no-repeat, repeat-x;
}

Note that the background image that you want at the top of the stack should go first in the image list.  Animating the backgrounds requires moving the background-position, also separated by commas:

@keyframes animatedBird {
	from { background-position: 20px 20px, 30px 80px, 0 0; }
	to { background-position: 300px -90px, 30px 20px, 100% 0; }
}
		
.animate-area	{ 
	animation: animatedBird 4s linear infinite;
}

The result is three moving pieces inside one element!

Of course this isn't an ideal case because you can't separately change background-positions and thus you need to work with the same duration for each background image.  Multiple animations can be set on selectors with CSS, but since it's the one property being changed, we're just out of luck!

ydkjs-4.png

Recent Features

  • 5 Ways that CSS and JavaScript Interact That You May Not Know About

    CSS and JavaScript:  the lines seemingly get blurred by each browser release.  They have always done a very different job but in the end they are both front-end technologies so they need do need to work closely.  We have our .js files and our .css, but...

  • Camera and Video Control with HTML5

    Client-side APIs on mobile and desktop devices are quickly providing the same APIs.  Of course our mobile devices got access to some of these APIs first, but those APIs are slowly making their way to the desktop.  One of those APIs is the getUserMedia API,...

Incredible Demos

  • Disable Autocomplete, Autocapitalize, and Autocorrect

    Mobile and desktop browser vendors do their best to help us not look like idiots by providing us autocomplete, autocorrect, and autocapitalize features.  Unfortunately these features can sometimes get in the way;  we don't always want or need the help they provide.  Luckily most browsers allow...

  • CSS Selection Styling

    The goal of CSS is to allow styling of content and structure within a web page.  We all know that, right?  As CSS revisions arrive, we're provided more opportunity to control.  One of the little known styling option available within the browser is text selection styling....

Discussion

  1. looks great as usually,
    now ready to make another article to combine this stuff ;)

  2. Great Tutorial David. Just with a few lines of CSS codes to create such a beautiful animation.
    Thanks.

  3. Nice tutorial! I never thought that making animation using so easy. But the problem is it doesn’t work in old browsers! :(

  4. Mich

    @Kiash: It’s time to stop using old browsers

  5. Crispen Smith

    David, I wanted to thank you for an awesome article. You got me thinking thought about the limitations and working within them.

    It seems that all is not lost when it comes to “story telling” via this technique.

    I did up a quick pen to explore these limitations.

    http://codepen.io/Crispen_Smith/pen/HGsxw

  6. Hichem benchaaben

    Cool but , why you not incorporate a fallback option for non supported browser in your tutorials ?
    Like you begin first of all by saying hey guys, check which browser can do this : ……
    Here is what usually will look like ……
    Here is the polyfills which you should do ….

  7. If your only concern is the markup and you don’t mind more complex CSS, an alternative is using pseudo elements which allows for the same animations using different durations: http://codepen.io/bananascript/pen/sBlhm

  8. Jesse

    Hi, great stuff!
    I’ve got a problem though – is there any way of getting this to work with multiple background images if I’m using the new extra-specific background-position as so:

    background-position: top 25% left 100px, bottom 50px right: 10%;
    

    ?????
    I’m pulling my hair out because I need to animate a multiple background system where I’m using this four-value background-position. Is it actually possible?
    Thanks in advance!

  9. Jesse

    OK, please excuse me, I’ve just answered my own question. It works!
    Just so that you know, it is imperative that when you’re using specific position syntax (background-position: bottom 10% right 50px; for example), when animating you cannot swap from one side to another (for example, you cannot animate from “background-position: bottom 10% right 50px” to “background-position: bottom 10% left 50px”; both values of start and end would have to be bottom and right in this case, not bottom right and then bottom left).

    Example of my code (yes, I know, it’s insane…):

    @keyframes bgMov { from {background-position: bottom -30% left 0, bottom 40% left 2%, top 60% left 0, top 95% right 0, top 78% left 0, top 65% right 0, top 59% left 0, top 55% right 0, top left;} to {background-position: bottom -30% left 586px, bottom 40% left 2%, top 60% left 0, top 95% right 520px, top 78% left 400px, top 65% right 260px, top 59% left 180px, top 55% right 120px, top left;} }
    

    Thanks anyway!

  10. I’ve modeled my code after http://davidwalsh.name/multiple-background-css-animations (demo http://davidwalsh.name/demo/multiple-background-css-animations.php).

    Here’s my adaptation (I’ll also paste it below): http://jsbin.com/cifig/1/

    The goal is to create an infinitely scrolling, two-layer parallax background. The effect works perfectly in Mac Chrome and Safari, but it stutters in Firefox.

    Any ideas why David Walsh’s version works in all three browsers, but mine fails? Thanks!

      body {
        background-color: black;
      }
    
      #container {
        position: absolute;
        top: 0; right: 0; bottom: 0; left: 0;
      }
    
      @-webkit-keyframes scrollBg {
        100% { background-position: 0 0; }
      }
    
      @keyframes scrollBg {
        100% { background-position: 0 0; }
      }
    
      .shotsBg1 {
        width: 100%;
        height: 100%;
        position: fixed;
        background-image: url(http://shotseverybody.com/images/shot_tile.png);
        background-size: 128px 156px;
        background-position: 0 -156px;
        opacity: 0.5;
        -webkit-animation: scrollBg 2.5s linear infinite;
        animation: scrollBg 2.5s linear infinite;
      }
    
      .shotsBg2 {
        width: 100%;
        height: 100%;
        position: fixed;
        background-image: url(http://shotseverybody.com/images/shot_tile.png);
        background-size: 64px 78px;
        background-position: 0 -78px;
        opacity: 0.25;
        -webkit-animation: scrollBg 5s linear infinite;
        animation: scrollBg 5s linear infinite;
      }
    

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!