Two background images. How to add two background images to one element? Improvements with CSS3

💖 Do you like it? Share the link with your friends

Using CSS 2.1 pseudo-elements allows you to have 3 levels of background, 2 fixed-size images, and multiple complex strokes on a single HTML element. This method significantly expands the design capabilities of web pages for all browsers that support CSS 2.1 pseudo-elements with positioning. No CSS3 support required.

Essentially, creating and working with CSS pseudo-elements (:before and :after) is similar to how you work with nested HTML elements within a target element. But with one significant advantage - everything is done outside of semantics, without using nested HTML elements.

To create multiple backgrounds and/or strokes, pseudo-elements are slid behind the content and anchored at the desired point in the HTML element using absolute positioning.


The pseudo element contains no real content and is positioned absolutely. This way it can be stretched over any area of ​​the "parent" element without affecting the content. To do this, you can use a combination of the top , right , bottom , left , width , and height properties.

What effects can you get?

Using just one element you can get parallax, multiple backgrounds (both colors and images), cropped background images, image replacement, expandable elements with images as strokes, flexible artificial columns, images extending beyond the borders of the element, multiple strokes and other popular ones effects that typically use image tags and/or additional HTML markup.

On the demo pages you can see the implementation of several popular web page design effects using this technique.

In addition, you can use styling changes for :hover to achieve more complex effects.

Sample Code: Multiple Background Images

Using this technique, you can reproduce the parallax effect with multiple background images (as used on the Silverback site), using only one HTML element.


The element gets its own background and required padding. The relative positioning of an element acts as a reference point for the absolute positioning of pseudo-elements. A positive z-index value allows you to adjust the position of pseudo-elements along the z axis.

#silverback ( position:relative; z-index:1; min-width:200px; min-height:200px; padding:120px 200px 50px; background:#d3ff99 url(vines-back.png) -10% 0 repeat-x ; )

Both pseudo-elements are positioned absolutely and placed on the sides of the element. A z-index value of -1 places the pseudo-element behind the layer content. This way, pseudo-elements are placed on top of the element's background and outline, but all content remains selectable and clickable.

#silverback:before, #silverback:after ( position:absolute; z-index:-1; top:0; left:0; right:0; bottom:0; padding-top:100px; )

Each pseudo-element has a repeating set of background images. To reproduce the parallax effect, you don't need anything else.

The content property allows you to add an image as generated content. Having two pseudo elements allows you to add 2 additional images to the element. They can be roughly positioned in pseudo-elements using other properties such as text-align and padding.

#silverback:before ( content:url(gorilla-1.png); padding-left:3%; text-align:left; background:transparent url(vines-mid.png) 300% 0 repeat-x; ) #silverback :after ( content:url(gorilla-2.png); padding-right:3%; text-align:right; background:transparent url(vines-front.png) 70% 0 repeat-x; )

Example code: flexible artificial columns

Another application of the described technique is the creation of flexible columns equal height without the use of images or additional related elements.


The HTML markup is very simple. Using classes for each div element instead CSS selectors 2.1, which are not supported by IE6. If there is no need to support IE6, then selectors can be used.

[content]
[content]
[content]

The container has a percentage width, relative positioning, and a positive z-index property value. Using overflow:hidden allows an element to wrap the content of its floating children and hides overflowing pseudo-elements. The background color provides the color for one of the columns.

#faux ( position:relative; z-index:1; width:80%; margin:0 auto; overflow:hidden; background:#ffaf00; )

Using relative positioning for div's descendant elements allows you to control the order of the columns regardless of their appearance in the original layout.

#faux div ( position:relative; float:left; width:30%; ) #faux .main (left:35%) #faux .supp1 (left:-28.5%) #faux .supp2 (left:8.5%)

The other two columns are created using pseudo-elements with backgrounds. You can use images as backgrounds if necessary.

#faux:before, #faux:after ( content:""; position:absolute; z-index:-1; top:0; right:0; bottom:0; left:33.333%; background:#f9b6ff; ) # faux:after ( left:66.667%; background:#79daff; )

Sample Code: Multiple Stroke

Multiple strokes are organized in almost the same way. Its use allows you to abandon images while maintaining the effect.


The element must have relative positioning and padding width sufficient to contain the extra stroke that will be created by the pseudo-elements.

#borders ( position:relative; z-index:1; padding:30px; border:5px solid #f00; background:#ff9600; )

The pseudo-element is positioned at the appropriate distance from the element's border, placed under the content layer using negative value z-index properties, and it is assigned the stroke and background as needed.

#borders:before ( content:""; position:absolute; z-index:-1; top:5px; left:5px; right:5px; bottom:5px; border:5px solid #ffea00; background:#4aa929; ) #borders:after ( content:""; position:absolute; z-index:-1; top:15px; left:15px; right:15px; bottom:15px; border:5px solid #00b4ff; background:#fff; )

Progressive Improvements and Legacy Browsers

IE6 and IE7 do not support CSS 2.1 pseudo-elements and ignore all:before and:after declarations. They will not bring all the improvements, but will retain the core functionality.

Attention when using Firefox 3.0

Firefox 3.0 supports CSS 2.1 pseudo-elements, but does not support their positioning. Because of this partial support, effects that explicitly depend on the width or height properties of the pseudo-elements can look terrible. There is no alternative way for Firefox 3.0 if you used the width or height properties. Sometimes some improvements can be achieved by adding display:block to the pseudo element's styles.

Before using techniques that require positioning pseudo-elements using the width or height properties, you need to consider how important it is to support Firefox 3.0 and the percentage of your users who use that browser.

This problem is completely resolved in applications that use absolute positioning instead of width or height properties.

Improvements with CSS3

All the examples that are implemented in this article can be improved using CSS3.

Using the border-radius , rgba , transforms properties and multiple CSS3 backgrounds in combination with pseudo elements can open up the possibility of implementing more complex effects. However, there are currently no browsers that support CSS3 animations or transformations for pseudo-elements.

The Future: CSS3 Pseudo-Elements

Suggested enhancements to CSS3 pseudo-elements (see the CSS3 Generated and Replaced Content Module document) include bound pseudo-elements (::before::before), multiple pseudo-elements (::after(2)), wrapping pseudo-elements (: :outside) and the ability to insert pseudo-elements for loaded parts of the document (::alternate).

Such changes will open up virtually unlimited possibilities for creating all kinds of effects using just one element and a set of pseudo-elements.

). Today we'll talk a little about another interesting feature - using multiple images in the background.

Background composition

There are many reasons why you might want to compose multiple images in the background at all, the most important of which are:

  • saving traffic on the size of images, if individual images weigh less in total than an 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 on top of the other. How is this problem usually solved? It’s very simple: for each background image, a block is created, to which the corresponding background image is assigned. Blocks are either nested inside each other or placed in a row with appropriate positioning rules. Here's a simple example:

A block with the class "fishing" inside "mermaid" is 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, fish can be moved, for example, with using JavaScript or CSS3 Transitions/Animations.

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

Multiple backgrounds

A new option added to CSS3 comes to the rescue - the ability to define multiple background images for one element. 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 the individual images separated by commas. Additional rules, also a list, can set positioning, repetitions and other parameters for each image. Note 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 separated into a separate block for subsequent manipulations, the entire 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 won’t show a picture of the result - believe me, it coincides with the two pictures above. But pay attention to the styles again, especially “background-repeat” - according to the specification, if part of the list at the end is missing, then the browser must repeat the specified list the required number of times 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 defined the ability to describe background images in a short form. How about multiple images? This 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 match the default value). By the way, if you want to set the color of the background image, this must be done in the very last layer.

Dynamic images

If the composition is static or dynamic at most 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 is an example from life - a theme with a dandelion in Yandex:


If you look 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 constantly scrolls, and dandelions fly across the screen.

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

How to add dynamics to multiple backgrounds? In such a situation, it turns out to be convenient that the browser scatters individual parameters in the internal representation background images according to the relevant rules. For example, for positioning there is “background-position”, and for shifts it is enough to change only this. However, there is a cost for using multiple images - this rule (and any similar one) requires you to list the position for all backgrounds defined for your block, and you cannot do this selectively.

To add animation to our fish background, 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) ( window.setTimeout(callback, 1000 / 60 ); )); ))();

And by the way, animations can also be done using CSS3 Transitions/Animations, but this is a topic for a separate discussion.

Parallax and interactivity

Finally, similar maneuvers can easily add parallax effects or interactive interaction with the background:

Multiple background images are useful in such scenarios, since while we are talking only about the background (and not the content), their use allows us to avoid littering the html code and DOM. But everything comes at a price: I can’t access individual composition elements by name, id, class or any other parameter. I must explicitly remember the order of elements in the composition in the code, and for every change in any parameter of any element, in fact, I must glue 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 convenient javascript code, which will take care of the virtualization of relationships with individual layers, while leaving the html code of the page as clean as possible.

What about compatibility?

All modern versions of popular browsers, including IE9+, support multiple images (you can check, for example, Caniuse).

You can also use Modernizr to provide alternative solutions for browsers that don't support multiple backgrounds. As Chris Coyier wrote in his post about 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're concerned about using JS to provide backwards compatibility, you can simply declare background twice, although 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 it uses the same engine as IE10.

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

In CSS 2, it is impossible to add two backgrounds to one element at the same time, so you have to nest one element inside the other and give each one its own background image. For complex layouts, such attachments can sometimes be counted at about a dozen. It is clear that such a pile-up 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 it in browsers.

Rice. 1. Block for the site

For simplicity, I will take the width of the block as a fixed size, and the height will vary depending on the content. The top and bottom parts are clearly visible in the drawing; I cut them out in the editor and fold them into layers in a separate file. The middle part must be chosen so that it repeats vertically without seams. The design has a well-defined repeating pattern, so there should be no difficulty in highlighting it. I copy and paste to the previous fragments. The result will be a picture like this (Fig. 2).

Rice. 2. Prepared images

In principle, you can save each fragment as a separate file, but CSS sprites (the so-called technology of 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 pictures are loaded and displayed faster in total.

The background itself is displayed by the background property, which also specifies 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 to not overlap, so I put them first (example 1).

Example 1. Several background images

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

Three backgrounds

Huitzilopochtli - "sorcerer of the hummingbird", 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 displays the top border of the block, the second background - the bottom, and the third - the vertical borders.

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

Rice. 3. Frame view in Safari browser

Using multiple backgrounds makes the situation much easier for developers, especially when laying out blocks. There's only one little thing left. It is necessary that the IE 6–8 browser cease to exist.

Today we will work on background images, which are set using the background property and its additional values. Let's look at a couple of practical examples of installing multiple backgrounds for the same element.

This can be useful in many cases and moments. Especially the use of pseudo elements in this case, since they are very flexible in parameters.

Lots of background images

In order not to create a block within a block, the easiest way is to add one line of rules to the main element and thus get the desired result. We can consider this a laconic option, especially since it eliminates the need to once again go into source. Everything will be done using CSS alone.

Blockimg( background: url("img/img2.png"),/*topmost background and then sequentially*/ url("img/img3.png"), url("img/img1.jpg"); background-position :370px center, 120px 150px, center center;/*position of images*/ background-repeat: no-repeat;/*repeat picture*/ background-color: #444;/*if background color is needed*/ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); margin: 100px auto 15px; box-sizing: border-box; padding: 25px; width:700px; min-height: 300px; ) /*shortened version*/ .blockimg ( background: url("img/img2.png") no-repeat 370px center, url("img/img3.png") no-repeat 120px 150px, url("img/img1.jpg") no-repeat center center ; margin: 100px auto 15px; box-sizing: border-box; padding: 25px; width:700px; min-height: 300px; )

Explanation. We give the element a background image, indicating the path to its location. Separated by commas, we are given the opportunity to enter many more backgrounds, as can be seen in the code above. The order of their numbers determines which image will be on top of the others. That is, the first background is higher than all the others, and then the sequence follows the principle of a regular graphic editor.

Next is indicated Extra options through individual properties: position, repetition, size, if necessary, then color. Please also note that all parameters are written separated by commas, in the same order as the number of the picture.

And one last detail. The entire code can be shortened by using just one generic property, background . There is a second option in the code example that shows how this is done.

Background image via pseudo element

Also, do not forget about alternative options, such as the before and after pseudo-elements. There is a positive advantage in their use - the image can be moved beyond the edge of the element, so that it does not disappear at the border, but is on top of it. This technique will come in handy if you need to create something like a 3D effect.

Blockimg( background: url("img/img1.jpg") no-repeat;/*element background*/ position:relative;/*positioning area*/ margin: 200px auto 15px; box-sizing: border-box; padding: 25px; width:700px; min-height: 300px; ) .blockimg::before( background: url("img/img1.png") no-repeat center center; bottom: 0; content: ""; height: 295px; left: 0; position: absolute;/*absolute positioning*/ right: 0; top: -150px; )

Explanation. In fact, everything is very simple. We set the background to the main element in the usual way. Next comes the key property position: relative; , which defines the area for moving another element that is in the main element and has the property position:absolute; .

Instead of another element, although formally it goes as a separate area, we use a pseudo-element. We give it an absolute position and position it in the place we need.

You can add multiple background images to one element at once through a single background property. This allows you to use one element to create a complex background or one image, displaying it several times with different settings. All images with their parameters are listed separated by commas, with the image that is displayed on top of the other images indicated first, and the last, respectively, the lowest image. Example 1 shows how to create a background with three images.

Example 1. Three backgrounds

Background

If you need to separately set some style property for the background, like background-size as in the example above, then the parameters for each background are listed separated by commas. The result of this example is shown in Fig. 1.

Rice. 1. Background with three images

Individual background images allow you to change their position and also animate them, as shown in example 2.

Example 2: Animated background

Background

Let's now consider how to use one picture to create a block with a frame (Fig. 2). The width of the block is fixed, and the height varies depending on the volume of the block’s contents.

Rice. 2. Hand-drawn frame

The figure clearly shows the upper and lower parts that need to be cut out graphic editor and position it horizontally. The middle part is selected so that it is repeated vertically without seams. The picture has a pronounced repeating pattern, so there should be no difficulty in highlighting it. The result will be a prepared image (Fig. 3). The checkered field indicates transparency; it allows you to set a colored background along with images and easily change it through styles.

Rice. 3. Image prepared for the background

The background itself is displayed by the background property, which also specifies the coordinates of the desired fragment. The parameters of each background are listed separated by commas, and in this case their order matters. We want the top and bottom of the block to not overlap, so we put them first (example 3). The background color is specified last.

Example 3. Several background images

Background

Huitzilopochtli - "sorcerer of the hummingbird", 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 displays the top border of the block, the second background - the bottom, and the third - the vertical borders. The last one is the color that is visible in the transparent central part of the block (Fig. 4).



tell friends