Jump to main navigation


Multiple background images with CSS2

080831

Here's an interesting way to add multiple background images to an element using CSS2. Before anyone gets too excited, since this technique uses generated content it doesn't work with IE6 nor IE7. Maybe IE8 will support generated content, but who knows.

Still it's fun to try, and if you can ignore IE, then this might be useful sometimes. It works in Firefox 2/3 and Opera 9 under Windows XP, at least.

In this article I'll first guide you through a basic example, and then we'll create a nicer box.

Tutorial: a basic example

Let's say we have a DIV with a tiled background image. We would like to add four more images, one at each corner of the DIV. We also want to be able to apply this to any box, which means we don't know the box's width nor height.

The idea is to use the :before and :after pseudo classes to add the extra images. We can actually add two images for each of those selectors, which makes a total of five images for the DIV! Let's see the code:

<div class='multipleBg'>... content here ...</div>

The HTML couldn't get any simpler! :) Now for the CSS:

.multipleBg  {
  background: url(pattern.gif);
}

.multipleBg:before, .multipleBg:after {
  display: block;
  height: 29px;
  font-size: 0;
}

.multipleBg:before {
  content: url(1.gif);
  background: url(2.gif) no-repeat 100% 0;
}

.multipleBg:after {
  content: url(3.gif);
  background: url(4.gif) no-repeat 100% 0;
}

Let's analyze the CSS code. The first statement simply assigns a background image to the DIV, which will be repeated to cover all its area.

The second statement is where the fun begins: first we set the display property to block, so we can add both the left and right corner images. We also set the height to match the height of the images. Finally we set the font size to 0: this is because if the corner images are small and/or the font size is resized to very big, the images can move down, away from the corners of the box. Give it a try and you'll see what I mean. All these rules apply to both :before and :after, so we combine them in one statement.

And then the nice trick to add two images instead of just one: the first one we add with the content property, using a url as the value. The second image we add with the background property, and position it to the top right.

You can see the result page here. Try resizing the browser and you'll see that the corner images stay in their place independently of the size of the DIV. Nice!

A nicer example

Let's use this technique to create a box with an image at the center, and four fancy images on each corner. The box doesn't have a fixed width or height, so we need to put each image in the corner independently. The result should look like this:

This is the box we are trying to achieve

<div class='nice'>... content here ...</div>
.nice {
  border: 1px solid #ffcf86;
  padding-left: 50px;
  padding-right: 50px;
  background: url(i5.gif) no-repeat 50% 50%;
}

.nice:before, .nice:after {
  display: block;
  height: 41px;
  margin-left: -50px;
  margin-right: -50px;
  font-size: 0;
}

.nice:before {
  content: url(i1.gif);
  background: url(i2.gif) no-repeat 100% 0;
}

.nice:after {
  content: url(i3.gif);
  background: url(i4.gif) no-repeat 100% 0;
}

The code is very similar to what we saw in the first example. The difference here is that we want to add some padding to the left and right of the DIV. The problem then is that the generated content will also be affected by this padding, moving the corner images towards the center of the DIV. This has an easy solution: simply compensate the DIV's padding with negative margins in both :before and :after. This brings back the images to the corners.

Have a look at the result here. Again, resizing the browser is safe, since the corner images will reposition themselves when the DIV dimensions change.

I think this technique allows for a huge variety of applications, both with fixed width and non-fixed width boxes. Unfortunately the fact that IE doesn't support generated content turns it into just an interesting experiment, but with very limited use (if any) in real applications. Hopefully IE8 will change things, but even then we'll still have to deal with IE7 for a long time (maybe even IE6).

Note that all this won't be much use once CSS3 becomes a reality, since it will offer multiple backgrounds as part of the specification.

You can follow any responses to this entry through the RSS 2.0 feed. Both comments and pings are currently closed.

2 comments to “Multiple background images with CSS2”

  1. #01 By Ralph, 090221 at 13:32

    Nice thing, hope IE will be cool for this soon as this is something
    very much needed in CSS thanks

  2. #02 By Arturas, 120718 at 06:10

    Thanks a lot! The code that I really needed!

Additional content and navigation

Categories

Main navigation menu