
CSS3 Work with multiple backgrounds
- Tutorial
We previously touched on the capabilities of the CSS3 Backgrounds and Borders module , considering working with shadows ( box-shadow ). Today we’ll talk a little about another interesting feature - the use of several images in the background.

There are many reasons why, in general, you may need to compose several images in the background, among them the most important are:
So, we need to place several background images one above the other. How is this problem usually solved? Very simple: a block is created for each background image, to which a corresponding background image is registered. Blocks are either nested or placed in a row with the corresponding positioning rules. Here is a simple example:
A block with the "fishing" class inside the "mermaid" is for demonstration purposes only.
Now a few styles:
Result:

In this example, three nested backgrounds and one block with fish, located next to the "background" blocks. In theory, fish can be moved, for example, using JavaScript or CSS3 Transitions / Animations.
By the way, in this example for ".fishing" uses the new syntax for positioning the background , also defined in CSS3:
Currently it is supported in IE9 + and Opera 11+, but it is not supported in Firefox 10 and Chrome 16. So, users of the last two browsers will not be able to catch the fish.
Let's go further. How to simplify this design?
A new option added to CSS3 comes to the rescue - the ability to define multiple background images for one element at once. It looks like this:
And related styles:
To define multiple images, you must use the background-image rule, listing the individual images separated by commas. Additional rules, also a list, you can set the positioning, repeats and other parameters for each of the images. Pay attention to the order of the images: the layers are listed from left to right from the top to the bottom.
The result is exactly the same:

If the fish do not need to be allocated in a separate block for subsequent manipulations, the whole picture can be rewritten with one simple rule:
Styles:
I will not give a picture with the result - believe me, it coincides with the two pictures above. But pay attention to the styles again, especially to the “background-repeat” - according to the specification, if part of the list is missing at the end, the browser should repeat the specified list as many times as necessary to match the number of images in the list.
In this case, this is equivalent to such a description:
If you remember CSS 2.1, it defines the ability to describe background images in short form. What about multiple images? It is also possible:
But note that now you can’t skip values just like that (unless they match the default value). By the way, if you want to set the color of the background image, you need to do this in the very last layer.
If the composition is static or dynamic no more than depending on the size of the container, then multiple backgrounds obviously simplify the page design. But what if you need to work with individual elements of the composition independently from javascript (move, scroll, etc.)?
How to add speakers to multiple backgrounds? In this situation, it turns out to be convenient that in the internal representation the browser scatters individual parameters of the background image according to the relevant rules. For example, for positioning there is a "background-position", and for shifts it is enough to change only it. However, there is also a fee for using multiple images - in this rule (and any similar one) you must list the position for all the backgrounds set for your block, and you cannot do this selectively.
To add animation to our background with fish, you can use the following code:
Where
Result ( video ):

And, by the way, animations can also be done through CSS3 Transitions / Animations, but this is a topic for a separate discussion.
Finally, with similar maneuvers, you can easily add the effects of parallax or interactive interaction with the background:
Multiple background images are convenient in such scenarios, since while we are talking only about the background (not the content), their use allows us to avoid littering the html code and the DOM. But you have to pay for everything: I can not access individual elements of the composition by name, id, class, or some other parameter. I must explicitly remember the order of the elements in the composition in the code, and for every change of any parameter of any element, in fact, I must stick together a line describing the values of this parameter for all elements and update it for the entire composition.
I am sure that this can be wrapped in a convenient javascript code that will take on the virtualization of relationships with individual layers, while leaving the html-code of the page as clean as possible.
All modern versions of popular browsers, including IE9 +, support multiple images (you can check, for example, with caniuse ).
You can also use Modernizr to provide alternate solutions to browsers that do not support multiple backgrounds. As Chris Coyier wrote in a note on layer order when using multiple backgrounds , do something like this:
If you are confused about using JS to provide backward compatibility, you can simply declare background twice, however, this also has its drawbacks in the form of a possible double loading of resources (this depends on the implementation of css processing in a particular browser):
If you have already started thinking about Windows 8, keep in mind that you can use multiple backgrounds when developing metro style applications, since the same engine is used inside as in IE10.
ps In the topic: I can not help but recall the phenomenal article about the principle of cicada .
Background Composition

There are many reasons why, in general, you may need to compose several images in the background, among them the most important are:
- saving traffic on the size of the images if the individual images in total weigh less than the image with flattened layers, and
- the need for independent behavior of individual layers, for example, when implementing the effects of parallax.
Classic approach
So, we need to place several background images one above the other. How is this problem usually solved? Very simple: a block is created for each background image, to which a corresponding background image is registered. Blocks are either nested or placed in a row with the corresponding positioning rules. Here is a simple example:
A block with the "fishing" class inside the "mermaid" is for demonstration purposes only.
Now a few styles:
.sample1 .sea, .sample1 .mermaid, .sample1 .fishing {
height:300px;
width:480px;
position: relative;
}
.sample1 .sea {
background: url(media/sea.png) repeat-x top left;
}
.sample1 .mermaid {
background: url(media/mermaid.svg) repeat-x bottom left;
}
.sample1 .fish {
background: url(media/fish.svg) no-repeat;
height:70px;
width:100px;
left: 30px;
top: 90px;
position: absolute;
}
.sample1 .fishing {
background: url(media/fishing.svg) no-repeat top right 10px;
}
Result:

In this example, three nested backgrounds and one block with fish, located next to the "background" blocks. In theory, fish can be moved, for example, using JavaScript or CSS3 Transitions / Animations.
By the way, in this example for ".fishing" uses the new syntax for positioning the background , also defined in CSS3:
background: url(media/fishing.svg) no-repeat top right 10px;
Currently it is supported in IE9 + and Opera 11+, but it is not supported in Firefox 10 and Chrome 16. So, users of the last two browsers will not be able to catch the fish.
Let's go further. How to simplify this design?
Multiple backgrounds
A new option added to CSS3 comes to the rescue - the ability to define multiple background images for one element at once. It looks like this:
And related styles:
.sample2 .sea {
height:300px;
width:480px;
position: relative;
background-image: url("media/fishing.svg"), url("media/mermaid.svg"), url("media/sea.png");
background-position: top right 10px, bottom left, top left;
background-repeat: no-repeat, repeat-x, repeat-x ;
}
.sample2 .fish {
background: url("media/fish.svg") no-repeat;
height:70px;
width:100px;
left: 30px;
top: 90px;
position: absolute;
}
To define multiple images, you must use the background-image rule, listing the individual images separated by commas. Additional rules, also a list, you can set the positioning, repeats and other parameters for each of the images. Pay attention to the order of the images: the layers are listed from left to right from the top to the bottom.
The result is exactly the same:

One rule
If the fish do not need to be allocated in a separate block for subsequent manipulations, the whole picture can be rewritten with one simple rule:
Styles:
.sample3 .sea {
height:300px;
width:480px;
position: relative;
background-image: url("media/fishing.svg"), url("media/mermaid.svg"), url("media/fish.svg"), url("media/sea.png");
background-position: top right 10px, bottom left, 30px 90px, top left;
background-repeat: no-repeat, repeat-x ;
}
I will not give a picture with the result - believe me, it coincides with the two pictures above. But pay attention to the styles again, especially to the “background-repeat” - according to the specification, if part of the list is missing at the end, the browser should repeat the specified list as many times as necessary to match the number of images in the list.
In this case, this is equivalent to such a description:
background-repeat: no-repeat, repeat-x, no-repeat, repeat-x;
Even shorter
If you remember CSS 2.1, it defines the ability to describe background images in short form. What about multiple images? It is also possible:
.sample4 .sea {
height:300px;
width:480px;
position: relative;
background: url("media/fishing.svg") top right 10px no-repeat,
url("media/mermaid.svg") bottom left repeat-x,
url("media/fish.svg") 30px 90px no-repeat,
url("media/sea.png") repeat-x;
}
But note that now you can’t skip values just like that (unless they match the default value). By the way, if you want to set the color of the background image, you need to do this in the very last layer.
Dynamic images
If the composition is static or dynamic no more than depending on the size of the container, then multiple backgrounds obviously simplify the page design. But what if you need to work with individual elements of the composition independently from javascript (move, scroll, etc.)?
By the way, here's an example from life - a topic with a dandelion in Yandex:
If you get into the code, you will see something like the following:
...
Blocks with the b-fluff-bg, b-fluff__cloud, and b-fluff__item classes contain background images that overlap each other. Moreover, the background with clouds constantly scrolls, and dandelions fly around the screen.
Can this be rewritten using multiple backgrounds? In principle, yes, but subject to 1) support for this feature in target browsers and ... 2) read on;)
How to add speakers to multiple backgrounds? In this situation, it turns out to be convenient that in the internal representation the browser scatters individual parameters of the background image according to the relevant rules. For example, for positioning there is a "background-position", and for shifts it is enough to change only it. However, there is also a fee for using multiple images - in this rule (and any similar one) you must list the position for all the backgrounds set for your block, and you cannot do this selectively.
To add animation to our background with fish, you can use the following code:
$(document).ready(function() {
var sea = $(".sample5 .sea")[0];
var fishesX = 30;
var fishesY = 90;
var fishX = 0;
var fishY = 0;
var mermaidX = 0;
var t = 0;
function animationLoop() {
fishesY = 90 + Math.floor(30 * Math.sin(t++ / 180.0));
if(--fishesX < 0) fishesX = 480;
mermaidX += 0.5;
if(mermaidX > 480) mermaidX = 0;
fishY = -10 + (10 * Math.cos(t * 0.091));
fishX = 10 + (5 * Math.sin(t * 0.07));
sea.style.backgroundPosition = "top " + fishY + "px right " + fishX + "px, " + mermaidX + "px bottom," + fishesX + "px " + fishesY + "px, top left";
window.requestAnimFrame(animationLoop);
}
animationLoop();
});
Where
window.requestAnimFrame = (function() {
return
window.requestAnimationFrame ||
window.msRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
(function(callback) { window.setTimeout(callback, 1000 / 60); });
})();
Result ( video ):

And, by the way, animations can also be done through CSS3 Transitions / Animations, but this is a topic for a separate discussion.
Parallax and Interactive
Finally, with similar maneuvers, you can easily add the effects of parallax or interactive interaction with the background:
Multiple background images are convenient in such scenarios, since while we are talking only about the background (not the content), their use allows us to avoid littering the html code and the DOM. But you have to pay for everything: I can not access individual elements of the composition by name, id, class, or some other parameter. I must explicitly remember the order of the elements in the composition in the code, and for every change of any parameter of any element, in fact, I must stick together a line describing the values of this parameter for all elements and update it for the entire composition.
sea.style.backgroundPosition = "top " + fishY + "px right " + fishX + "px, " + mermaidX + "px bottom," + fishesX + "px " + fishesY + "px, top left";
I am sure that this can be wrapped in a convenient javascript code that will take on the virtualization of relationships with individual layers, while leaving the html-code of the page as clean as possible.
What is there with compatibility?
All modern versions of popular browsers, including IE9 +, support multiple images (you can check, for example, with caniuse ).
You can also use Modernizr to provide alternate solutions to browsers that do not support multiple backgrounds. As Chris Coyier wrote in a note on layer order when using multiple backgrounds , do something like this:
.multiplebgs body {
/* Awesome multiple BG declarations that transcend reality and imsourcess chicks */
}
.no-multiplebgs body {
/* laaaaaame fallback */
}
If you are confused about using JS to provide backward compatibility, you can simply declare background twice, however, this also has its drawbacks in the form of a possible double loading of resources (this depends on the implementation of css processing in a particular browser):
/* multiple bg fallback */
background: #000 url(...) ...;
/* Awesome multiple BG declarations that transcend reality and imsourcess chicks */
background url(...), url(...), url(...), #000 url(...);
If you have already started thinking about Windows 8, keep in mind that you can use multiple backgrounds when developing metro style applications, since the same engine is used inside as in IE10.
ps In the topic: I can not help but recall the phenomenal article about the principle of cicada .