Multiple background in css3. Multiple Backgrounds with CSS, or Multiple Backgrounds

). Today we will talk a little about another interesting feature - the use of multiple images in the background.

Composition of backgrounds

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 images, if the individual images together weigh less than the image with flattened layers, and
  • the need for independent behavior of individual layers, for example, when implementing parallax effects.
There may be other reasonable reasons :)

Classic approach

So, we need to place several background images one above the other. How is this task usually solved? It's very simple: a block is created for each background image, and the corresponding background image is assigned to it. Blocks are either nested within each other or placed in a row with the appropriate positioning rules. Here's a simple example:

Block with class "fishing" inside "mermaid" for demonstration purposes only.

Now some 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, there are three nested backgrounds and one block with fish, located next to the "background" blocks. In theory, the fish can be moved, for example, using JavaScript or CSS3 Transitions / Animations.

By the way, this example uses the new background positioning syntax for ".fishing", also defined in CSS3:
background: url (media / fishing.svg) no-repeat top right 10px;
It is currently supported in IE9 + and Opera 11+, but not supported in Firefox 10 and Chrome 16. So users of the last two browses will not be able to catch a fish yet.

Multiple backgrounds

A new feature added in CSS3 comes to the rescue - the ability to define multiple background images for one element at once. It looks like this:

And the corresponding 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 individual images separated by commas. Additional rules, also a list, can be used to set positioning, repetitions and other parameters for each of the images. Pay attention to the order in which the images are listed: layers are listed from left to right from topmost to bottommost.

The result is exactly the same:

One rule

If the fish do not need to be selected 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 at the end is missing, then the browser must repeat the specified list as many times as necessary to match the number of images in the list.

In this case, it is equivalent to this 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 a concise manner. How 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 just skip values ​​(unless they coincide with the default). By the way, if you want to set the color of the background image, it must be done 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 real life - a theme with a dandelion in Yandex:


If you dig into the code, you will see something like this:
...

Blocks with classes "b-fluff-bg", "b-fluff__cloud" and "b-fluff__item" contain background images that overlap each other. Moreover, the background with clouds is constantly scrolling, and dandelions fly across the screen.

Can this be rewritten using multiple backgrounds? In principle, yes, but provided 1) support for this feature in target browsers and ... 2) read on;)

How do I add speakers to multiple backgrounds? In such a situation, it turns out to be convenient that in the internal view the browser scatters the individual parameters of the background image according to the appropriate rules. For example, for positioning there is a "background-position", and for offsets, it is enough to change only it. However, there is a charge for using multiple images - this rule (and any similar rule) must list the position for all 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"); 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) (60 );));)) ();

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 come in handy in such scenarios, since while we're only talking about the background (and not the content), using them allows you to avoid cluttering your html code and the DOM. But you have to pay for everything: I cannot refer to individual elements of the composition by name, id, class, or any other parameter. I must clearly remember the order of elements in the composition in the code, and for each change of any parameter of any element, in fact, I must glue the 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 convenient javascript code, which will take over the virtualization of relationships with individual layers, while leaving the html-code of the page as clean as possible.

What's 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 browsers that don't support multiple backgrounds with alternative solutions. As Chris Coyier wrote in his 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 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've 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 internally as in IE10.

P.s. On the topic: I can't help but remember the phenomenal article about

Task

Cross-browser add two background images for the block.

Solution

Background pictures are quite actively used to create blocks, because with their help the most bizarre designs are formed. In particular, you can add decorative corners, vertical and horizontal lines, and much more to an element.

Cross-browser (i.e. for all browsers, including older versions) you cannot add two backgrounds to one element, so you have to go for the trick and nest one element inside the other. At the same time, for each nested element, its own background image is created, due to the imposition of blocks, the effect is born that there is one element, and it contains several background images. It is important here not to add padding to the outer elements, otherwise the effect will be lost.

As an example, consider creating vertical decorative lines to the left and right of a block. To do this, first prepare images that should be repeated vertically without seams. In fig. 1 shows the background image that will be applied to the first element, it will form the border on the left, and in fig. 2 background for a nested element that adds a border to the right.

Rice. 1. Background picture for the border on the left

Rice. 2. Background picture for the border on the right

As a block element to which a background is added, the tag is usually used

due to its convenience and versatility. The background image is set via the background style property, as shown in example 1.

Example 1. Two background images

HTML5 CSS 2.1 IE Cr Op Sa Fx

Two background images

During 11 months of the watch, radio operators conducted 8642 communication sessions with a total volume of 300625 groups. This is only meteo and aerial telegrams. Received from the radio station Cape Chelyuskin 7450 groups.


The result of this example is shown in Fig. 3.

Rice. 3. View of the block with two background pictures

In this example, so that the background is added only to the desired tag

, and not to all similar elements on the page, a class named block is used, to which all the style properties are applied. To style only nested
the example specifies a context selector (.block div construction), it defines the style for the tag only
located inside
.

In CSS 2, adding two backgrounds to one element at the same time is not realistic, so you have to nest one element inside the other and set its own background image for each. For complex layouts, such attachments can sometimes be counted about a dozen. It is clear that such a heap does not lead to anything good, but what to do? It turns out there is something! In CSS 3, you can add multiple background images to any element at the same time. So we take the block drawing (Fig. 1), cut it into pieces and start testing in browsers.

Rice. 1. Block for the site

For the sake of simplicity, the width of the block will be a fixed size, and the height will stretch depending on the content. The figure clearly shows the upper and lower parts, I cut it out in the editor and fold it in layers in a separate file. The middle part must be chosen so that it repeats vertically without seams. The drawing has a well-defined repeating pattern, so there should be no difficulties with selection. Copy and paste to the previous fragments. As a result, you will get such a picture (Fig. 2).

Rice. 2. Prepared images

In principle, you can save each fragment as a separate file, but CSS sprites (this is the name of the technology for gluing several images into one) have a number of advantages. Firstly, the number of requests to the server is reduced due to the reduction in the number of files, and, secondly, the figures in total are loaded and displayed faster.

The background itself is displayed by the background property, it also sets the coordinates of the desired fragment. The parameters of each background are listed separated by commas, and in this case their order matters. I want the top and bottom of the block not to overlap, so I put them first (example 1).

Example 1. Multiple background images

HTML5 CSS2.1 CSS3 IE 8 IE 9 Cr Op Sa Fx

Three backgrounds

Huitzilopochtli - "the hummingbird sorcerer", the god of war and the sun.

Tezcatlipoca - "smoking mirror", the main god of the Aztecs.

Human sacrifices were made to both gods.



The first background draws the top border of the box, the second background draws the bottom, and the third the vertical borders.

Checking in browsers. Internet Explorer 8 did not display any images at all, other browsers (IE 9, Opera 10.60, Firefox 3.6, Chrome 5, Safari 5) displayed the frame correctly (Fig. 3).

Rice. 3. View of the frame in the Safari browser

Using multiple backgrounds makes the situation much easier for developers, especially when layout blocks. There is only one little thing left. The IE 6-8 browser needs to cease to exist.

). Today we will talk a little about another interesting feature - the use of multiple images in the background.

Composition of backgrounds

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 images, if the individual images together weigh less than the image with flattened layers, and
  • the need for independent behavior of individual layers, for example, when implementing parallax effects.
There may be other reasonable reasons :)

Classic approach

So, we need to place several background images one above the other. How is this task usually solved? It's very simple: a block is created for each background image, and the corresponding background image is assigned to it. Blocks are either nested within each other or placed in a row with the appropriate positioning rules. Here's a simple example:

Block with class "fishing" inside "mermaid" for demonstration purposes only.

Now some 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, there are three nested backgrounds and one block with fish, located next to the "background" blocks. In theory, the fish can be moved, for example, using JavaScript or CSS3 Transitions / Animations.

By the way, this example uses the new background positioning syntax for ".fishing", also defined in CSS3:
background: url (media / fishing.svg) no-repeat top right 10px;
It is currently supported in IE9 + and Opera 11+, but not supported in Firefox 10 and Chrome 16. So users of the last two browses will not be able to catch a fish yet.

Multiple backgrounds

A new feature added in CSS3 comes to the rescue - the ability to define multiple background images for one element at once. It looks like this:

And the corresponding 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 individual images separated by commas. Additional rules, also a list, can be used to set positioning, repetitions and other parameters for each of the images. Pay attention to the order in which the images are listed: layers are listed from left to right from topmost to bottommost.

The result is exactly the same:

One rule

If the fish do not need to be selected 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 at the end is missing, then the browser must repeat the specified list as many times as necessary to match the number of images in the list.

In this case, it is equivalent to this 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 a concise manner. How 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 just skip values ​​(unless they coincide with the default). By the way, if you want to set the color of the background image, it must be done 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 real life - a theme with a dandelion in Yandex:


If you dig into the code, you will see something like this:
...

Blocks with classes "b-fluff-bg", "b-fluff__cloud" and "b-fluff__item" contain background images that overlap each other. Moreover, the background with clouds is constantly scrolling, and dandelions fly across the screen.

Can this be rewritten using multiple backgrounds? In principle, yes, but provided 1) support for this feature in target browsers and ... 2) read on;)

How do I add speakers to multiple backgrounds? In such a situation, it turns out to be convenient that in the internal view the browser scatters the individual parameters of the background image according to the appropriate rules. For example, for positioning there is a "background-position", and for offsets, it is enough to change only it. However, there is a charge for using multiple images - this rule (and any similar rule) must list the position for all 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"); 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) (60 );));)) ();

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 come in handy in such scenarios, since while we're only talking about the background (and not the content), using them allows you to avoid cluttering your html code and the DOM. But you have to pay for everything: I cannot refer to individual elements of the composition by name, id, class, or any other parameter. I must clearly remember the order of elements in the composition in the code, and for each change of any parameter of any element, in fact, I must glue the 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 convenient javascript code, which will take over the virtualization of relationships with individual layers, while leaving the html-code of the page as clean as possible.

What's 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 browsers that don't support multiple backgrounds with alternative solutions. As Chris Coyier wrote in his 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 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've 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 internally as in IE10.

P.s. On the topic: I can't help but remember the phenomenal article about

Task

Add two background images for the block using CSS3.

Solution

Modern browsers allow you to add an arbitrary number of background images to an element, listing the options for each background, separated by commas. It is enough to use the universal property background and specify one background for it first and the second separated by commas.

As an example, consider creating vertical decorative lines to the left and right of a block. To do this, first prepare images that should be repeated vertically without seams. In fig. 1 shows a background image that will be displayed on the left edge, and in fig. 2 picture to display on the right edge.

Rice. 1. Background picture for the border on the left

Rice. 2. Background picture for the border on the right

As a block element to which a background is added, the tag is usually used

due to its convenience and versatility, in order to distinguish it from the rest of the elements, the block class is added to it (example 1).

Example 1. Two background images

HTML5 CSS3 IE Cr Op Sa Fx

Two background images

During 11 months of the watch, radio operators conducted 8642 communication sessions with a total volume of 300625 groups. This is only meteo and aerial telegrams. Received from the radio station Cape Chelyuskin 7450 groups.


The result of this example is shown in Fig. 3.