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 { }
}
Clear and simple explanation. Thanks.
It would be interesting if they allowed another value for a z-index like effect.
Like:
background: url(number.png) 600px 10px 5 no-repeat
Possibly… but that might be overly complicated. What advantages does that bring over just changing the order?
Switching background layers with javascript? That’s about all I can come up with.
But that leads me to another question. How does this change how jquery targets it with .css() ?
While you bring it up… I would love to see a simple property for these backgrounds in css for a couple things (I know they are possible, but a simpler syntax would be awesome).
For lack of a better example, lets say a black and gray checkered background, with two soid block images. Such as a “checker” property of even a “fade-left: value;” type of thing, for faded images.
I dunno but it would be crazy.
Think allowed transparency would be cool and creative stuff. Tried rgba color on top. Not possible.
I heard it’s coming ;-)
You’ll be able to put lots of things in a “image()” expression, especially rgba colors; and “image()” expressions can then be used anywhere an image is legal.
Modernizr isn’t necessary for fallback. Add a standard background before the multi-background property. Modern browsers will use the last read declaration while older browsers should ignore the one they don’t understand.
Beat me to it!
The only problem with that approach is newer browsers will get penalized by having to load the fallback even if they don’t need it. A modern browser will only load resources if a selector matches an element, so the modernizr selector will not match for newer browsers and the fallback image will not be loaded.
Modernizr’s approach is to give developers a way only penalize non-conforming browsers by loading polyfills or some sensible fallback.
I totally prefer the petty penalty to newer browsers caused by a duplicated property than depending on javascript to have a css fallback.
Some browsers would download this extra graphic, some wouldn’t.
Once upon a time a tried to make web2.0 pretty buttons with mixture of gradients. So I used CSS3 gradients for webkit and gecko. I needed two fallbacks. For Opera I used multiple backgrounds (gradients in png.), and for older browsers I used one background.
In the image background case there was no penalization, because I used the same images that created wanted gradientish background. Fallback in this case was only narrowing the number of the images, so buttons were simpler.
In the gradient background case Chrome and FF didn’t download fallback images (those for Opera), but Safari did :P.
Downloading and initializing JS script (Modernizer) is not penalization?
Requiring Javascript for functionality always bothers me. Especially when it’s simply used for deprecation.
It seems to me that people who use older browsers are most likely to have JS disabled by default.
Cool
Regarding fallbacks for browsers that don’t have support for multiple backgrounds, it’s not necessary to rely on Modernizr. You can create an effective fallback by simply declaring two background properties in the same declaration.
Example:
…Holsters weapon ;)
Alrighty I tested that out and you fellas are correct.
http://jsbin.com/egabe5/2/edit
I tested it in Firefox 2 which doesn’t support multiple BG’s and it does snag the first declaration. That’s a great way to go. I was long under the assumption that the second would overwrite the first (being the same property) and show nothing. Not the case.
It seems that Chris becomes so engaged with the new possibilities of CSS that he forgets the very basics of it ;)
very nice..thanx!!
Thanks for this Chris, I couldn’t figure out why an extra rgba(255,255,255,.3) bg on hover wasn’t working.
ah man you always make things so much easier than i think it would be. thanks dude. you have really helped my progress.
In my opinion, the existing order of stacking actually makes more sense. Given that CSS was developed to separate design from markup, it makes sense that it would follow a “designer-ish” paradigm rather than a markup paradigm. In this case, it’s akin to layers in graphics packages like Photoshop, where the “top” layer is the one that has priority/visibility.
Thanks for the tip. I always did this:
body {
/*...background*/
margin: 0; padding: 0;
}
#border-wrapper {
/*...background*/
margin: 20px; padding: 20px; /*optional*/
}
Something I tried recently was putting one background on the HTML element and another on the BODY.
Bingo, this works like a charm. I tried using a tiled bg on HTML and for example, a centered transparent png (something like an alpha gradient) on BODY. This method seemed to work flawlessly on pretty much any browser alongside dd_belated png fix. Would be interested to know if anyone else has used this method, please correct me if I am wrong
Is it possible to see an example somewhere? I’m struggling to imagine it? It sounds cool, though!
Here’s an example… http://bit.ly/gfNJzF.
Please excuse the poor legibility and client’s unpolished logo. The paper texture is assigned to the HTML tag and the overlaying map is on the BODY
Alistair – are you aware that your body style has a declaration that says:
color: 333px;
Yeah, the stacking order tripped me up when I was trying to create multiple background images with a background gradient underneath it all. For a while I couldn’t figure out why only the gradient was showing up (it was listed first, then the other images applied).
As you said, every developer I’ve talked to has found this counter-intuitive, but it’s just one of those things you only have to learn once; though it makes me wonder why the people writing the spec created that order.
Interestingly, it’s not just images that can be layered, but css gradients too.
I had problem in IE 8 .
will not display
-moz-border-radius
-moz-box-shadow
I hope you do know those are vendor specific CSS selectors that only work in Firefox, hence the prefix “moz” of “Mozilla”.
The Standard doesn’t make sense to me.
I would say the first declared should be at the lowest level. An artist doesn’t paint the top layer first then try and add layers below.
Logically we tend to start with backgrounds, laying down (say) an image, then perhaps a 100% div over the top with a semi-transparent image, and so on.
Obviously the people who wrote this part of the Spec aren’t designers or artists. Or Vulcans, for that matter ;-)
It would be nice if there was a way to add a second background without repeating the whole attribute.
example:
Imagin generating cards through css, you have a frame with images and a pattern
Is there a way today** to accomplished that whithout js**?
how to get the css3 multiple background property if there have to be used for a same tag with different property to be used.