Andi Smith

CSS3 Backgrounds of the Future

Whilst we've been busy supporting older versions of Internet Explorer, a few new CSS features for backgrounds have sprung out of the woodwork and in to our browsers.

  • background-size
  • background-clip
  • and background-origin

These features have been hiding behind their more popular gradient background color cousins; but are worth making a note of, especially if you're creating sites for mobile phones and recent browsers; and the best news is that they are completely prefix-free!

Let's take a look at what these properties are, what they do and afterwards we'll have some fun with animating backgrounds. Yay!

To demonstrate how these features work, I've put together some demos. For each demo, unless otherwise stated the following CSS background properties are set:

  • background-image: red url(img/ice.jpg)
  • background-position: top left (default)
  • background-repeat: no-repeat

Please note, as these are live demos, you will need Firefox 4+, Internet Explorer 9+, Opera 10.5+, Safari 3+ or any Chrome to view them.

background-size

If you've been developing for mobile phones with high density pixels, you may have already come across background-size. For a long time on the web we were unable to resize images when they were used as a background but with CSS3 property background-size, not only are we able to specify the size of a background we are able to make it relative to the containing element.

Here's the syntax and the possible options:

background-size: auto | cover | contain | value [value];

To show how each option works, let's use some examples:

auto, contain and cover

  • background-size:auto;

  • background-size:contain;

  • background-size:cover;

You'll already be familiar with background-size: auto (the example on the left). This is the default setting for background-size and what almost every background on the web so far uses. This setting doesn't resize your image at all - if it's too big it'll cut off a chunk of the image. If it's too small it'll either leave a gap or repeat, depending on the value of your background-repeat.

With background-size:contain (middle), the background image will be resized so that the entire image fits in the space whilst keeping its original proportions. This will mean that unless your container is to the same proportion as your background image there will be a gap. In our case it's at the bottom and in red as the background-color has filled in the gap for us.

If you can't guarantee the size of the background and you don't want a gap, background-size:cover may be exactly what your looking for (on the right). This option will resize the image so that the shortest dimension (width or height) exactly fits the space whilst keeping the images original proportion. What this means is part of your image will be cut off. Depending on the proportions of the image will depend on how much.

So to recap:

  • Use contain and your background image height and width will be <= to the container.
  • Use cover and your background image height and width will be >= to the container.

Percentages

  • background-size:100%;

  • background-size:50%;

  • background-size:100% 100%;

Now we've covered the three keywords, it's time to take a look at the other values that can be placed in to background-size. All values can either be specified as a single value or two separate values - one for the width and one for the height.

In the case where only one percentage value is specified, background-size will use the value specified to resize the width regardless of whether the width or height is the bigger dimension, which is why in our first example (above left) there is a small gap at the bottom of the container.

Using percentage values allow us to specify what the percentage of the containing element the image appears in - NOT what percentage of the overall image dimensions we wish to show. In our middle example above the image is 50% of the total container. Again, the 50% is taken from the width value.

Even though the images are appearing at a smaller size, the image is still loaded from the server at its full size - resizing is occuring client-side, so the browser will still have to download the full size image.

We can use multiple values to specify different dimensions for the width and height. In the case of our example above on the right, we have specified a width of 100% and a height of 100%. This is not the same as cover mode - as we are specifying both dimensions the image will be resized disproportionally, which depending on the image and the values used may or may not be noticeable.

  • background-size:50% 100%;

  • background-size:150%;

  • background-size:150%;
    background-position:center

As you can see in our first example here the image has been disproportionally stretched when I've specified one dimension as half of the other. Much more noticeable!

In our second two examples, a percentage value larger than 100% is used. In these examples, the image is shown as 150% bigger than the containing element (again, not 150% of the image). The third example here also centers the image, as it's entirely possible to use all the other background css properties whilst using background-size.

  • background-size:50%;
    background-position:right bottom;

  • background-size:50%;
    background-position:center;

  • background-size:50%;
    background-repeat:repeat;

The first two examples here use background-position to change the positioning of the background image. Don't forget you can use percentages and other values for positioning images if you wish.

In our third example, we are repeating the image, which creates a tile effect even though it has been resized to 50% of the size of the original image.

Percentages are very useful, but sometimes you want to be explicit with the size of your background image. Let's continue.

Length values

  • background-size:80px auto;

  • background-size:auto 200px;

  • background-size:80px 200px;

The most common length values are pixels (px), but you could use other valid length measurements if you wish. In the first example (left), background- size is set to 80px auto; which means that the width will be set to exactly 80px and the height will be proportionate to that value. In this example, the auto value is actually superfluous - the default is already auto so it is not required. In our second example (middle), we have set the width to auto and the height to 200px which means the width will be set in proportion to the height. In our final background-size example, we've stretched the image by specifying a width and height that isn't suited for the image.

Multiple backgrounds

If you're using multiple backgrounds, you can have multiple background sizes by separating the values with a comma.

  • background-image:url(img/bg-grid.gif),url(img/ice.jpg);
    background-size:auto, 50%;

  • background-image:url(img/bg-grid.gif),url(img/ice.jpg);
    background-size:60%, 100%;

  • background-image:url(img/bg-grid.gif),url(img/ice.jpg);
    background-size:32px 100%, 90% 150px;

These examples have different background sizes for each image - simply list the background sizes in the same order as your images. Remember that multiple images are stacked with the first listed image at the top and the last listed image at the bottom (top to bottom).

The third example (right) mixes percentages and lengths to create a cocktail of background-size goodness.

Let's move on to background-clip, but if you're interested you can read more about background size on MDN.

background-clip

background-clip allows us to specify what area of the container we wish to clip our backgrounds to. There are three options available: border-box, padding-box and content-box.

background-clip: border-box | padding-box | content-box
  • background-clip:border-box;
    (this is the default, you don't need to specify it!)

  • background-clip:padding-box;

  • background-clip:content-box;

border-box (left) is the default option, and this means the background will sit under the border. This isn't noticeable unless you have a transparent, semi transparent or semi solid border (as we have here). As you can see in our example on the left, the background sits under the border. If you're wondering why the background sits under the border on the bottom right, but not the top left; it's due to the background-origin, which I'll explain shortly.

padding-box (middle) clips the image so it no longer appears under the border. The background image will start at the top left of the inside of the containing element and finish at the bottom right of the containing element.

content-box (right) clips the image to the area where the content can sit. That is - the background begins where the padding finishes. In the case of our example, the padding is 5px wide all the way round so this creates a 5px clipping border.

More information on background-clip is available on MDN.

background-origin

The final CSS3 background property I wanted to cover was background-origin. As you would have noticed from our example above, the background for the border-box didn't sit under the left and top borders. The reason for this is because of the background-origin which determines where the background should start - and it's default value is padding-box.

background-origin: padding-box | border-box | content-box;
  • background-origin:padding-box;

  • background-origin:border-box;

  • background-origin:content-box;

As before, padding-box starts our background at the point where padding begins.

border-box allows us to start our background where the border starts - at the top left of the container element.

content-box starts our background where our content begins (after the padding). If you look back to our example of background-clip:content-box you may notice that the image in our container starts 5px after it does in this example. This is because background-origin determines where an image starts, not background-clip.

There's more information on background-origin at MDN!

Animations

Now we're done with learning the properties, let's have some fun with background animations using CSS3 transitions and animations! There's nothing really to learn in this section, I was just playing around. If you want to know more about CSS3 transitions and animations there are lots of useful resources already out there - Google is your friend!

Of the three CSS3 properties we've covered today, only background-size can be animated. However, background-color and background-position can also be animated, as you'll see below (providing your browser supports animation - sorry Opera/IE9 users).

  • Hover to zoom!

  • Hover to move background!

  • Hover to move background!

The first example uses background-size to increase the size of the image on hover. The second (middle) example actually uses background-repeat and background-position to create a film reel effect. The third example uses background-size again to zoom in from a small image.

  • Hover to change color!

  • Hover to change size!

  • Hover to Mother Effing Rainbow!

In these examples, the first example (left) changes the background color from red to blue on hover; the second example uses both width and height background sizes to go from a lamppost to a letterbox effect; and the third example is a Mother Effing Rainbow effect in tribute to mothereffingtextshadow.com.

Enjoy the animations, and I hope this has been useful to you! Thanks for reading!