Stacking Order of Multiple Backgrounds

Avatar of Chris Coyier
Chris Coyier on (Updated on )

Multiple background images is a cool feature of CSS3. The syntax is easy, you just comma separate them. I find it’s easiest/best to use the background shorthand property so you can declare the position and repeating and whatnot and keep them all grouped together. What isn’t obvious while looking at the syntax is which image is on top in the vertical stacking order when those images overlap. The spec is clear in this regard and browser implementations follow. The first is on top and they go down from there.

background: 
   url(number.png) 600px 10px no-repeat,  /* On top,    like z-index: 4; */
   url(thingy.png) 10px 10px no-repeat,   /*            like z-index: 3; */
   url(Paper-4.png);                      /* On bottom, like z-index: 1; */

It’s like z-index but this isn’t z-index, it’s parts of one single element.

I think it’s slightly confusing since it’s the opposite of how HTML works naturally. If all elements have the same z-index (and are positioned in some way and overlap) the last element will be on top, not the first. Not that big of a deal though, just need to learn it once.

The big thing to remember is that if you were to use one of the backgrounds for a fully opaque / fully repeating image, list that one last not first, otherwise it will cover all the others up.

Also remember that while multiple backgrounds is totally radical, the fallback for browsers that don’t support it is that it displays nothing at all for the background, so be careful there. The best way to handle it, as always, is Modernizr. They even use it as the demo right on the homepage of their site (adjusted for clarity):

.multiplebgs body {
  /* Use awesome multiple backgrounds here */
}
.no-multiplebgs body {
  /* laaaaaame fallback */
}

These days (Update May 2019), I probably wouldn’t worry about that at all as browser support for this is extremely high. Plus you could do it in CSS like:

@supports (background-image: url(foo.jpg), url(bar.jpg)) {
  body { } 
}