Digital Web Magazine

The web professional's online magazine of choice.

Web Design 101: Backgrounds

Got something to say?

Share your comments on this topic with other web professionals

In: Columns > Web Design 101

By Paul O'Brien

Published on May 21, 2007

The CSS background property allows you to apply background colors and images to elements as required. But there are plenty of strange quirks and bugs that may surprise the unwary developer.

What is the background anyway?

The background of an element is the total width and height of the element, and includes the padding and borders that have been set on that element. It does not include the margins of the element. Therefore a background applied to an element will be underneath the foreground content of that element and include the padding, and it will also be underneath any borders that have been declared.

If an element has transparent borders, you should see the image underneath the borders—but note that IE6 and older don’t support transparent borders, and get this part of the spec wrong anyway, as the background only goes to the inside edge of the borders.

This is best demonstrated with a small example that you can test in IE6 and Firefox to compare the differences.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <title>Background test</title>
    <style type="text/css">
      #test{
        width: 100px;
        height: 100px;
        background: red;
        border: 10px dashed green;
      }
    </style>
  </head>
  <body>
    <div id="test">test</div>
  </body>
</html>

I have used green dashed borders so you can see the background in the gaps. As you can see, in IE (including IE7) the background color only reaches the inside edge of the border, whereas most other browsers slide the background color right under the border until it meets the outside edge of the container.

Image showing the problem: background area in IE and Firefox

In day-to-day usage this is rarely a problem, but is something you should be aware of.

Background Properties

In most cases, the following will refer to both block level and inline elements, with the exception that the tiling and positioning of the background-image on inline elements is undefined in the CSS2.1 specification.

The background properties are:

Let’s look at each of the properties in turn, how they work, and what they do.

background-color

Possible values: color | transparent | inherit

As you might expect, this simply sets the background color of an element. It can be specified in several different ways:

background-color: #000000;

or in three digit pairs:

background-color: #000;

You can also use one of the available color keywords instead:

background-color: red;

Or finally, you can use the rgb color method:

background-color: rgb(0,0,0);

(The W3C has more information on the different methods of applying color.)

The initial, or default, value of an element’s background is transparent—this allows an element to be placed on top of another element, and allows the background to shine through. It will not usually be necessary to declare this, unless you are overriding a previous background color that was set for this element.

Incidentally, a good habit to get into is to always set a foreground color at the same time you set a background color, to avoid the possibility of both the foreground and background being the same or a very similar color (either through inheritance or via user stylesheets). While you cannot always do this—for example if your background is transparent—is something to bear in mind and to check while coding.

When you apply a background-color to an element, there must be some part of that element visible for the background to show. If the element has no height—as is the case when it contains only floated children—then there will be no background color visible. This is a common mistake by beginners, and you must ensure that your container actually takes up some space on the screen if you want your background to be seen.

background-color: inherit;—Inherit allows the element to inherit its parent’s background-color. It is often mistakenly thought that background colors are inherited by default, but this is not the case—the fact that you can see the parent’s background color on a child element is because the child element’s background is transparent.

background-image

Possible values: uri | none | inherit

The background-image property allows you to place an image in the background of the element concerned—all that is needed is to set the correct path to the image:

background-image:url(example-image.gif);

Note that the path of the image is relative to the location of the css file, and not the html page that calls it, so make sure you are pointing to the correct location—here, assuming that our CSS is in a /css folder, we are pointing to an image located in the /images folder which is at the same level as the CSS folder:

background-image:url(../images/example-image.gif);

There is no need to wrap quotation marks around the url—they are optional—but using them is valid:

background-image:url("../images/example-image.gif");

Single quotation marks are also allowed—however, singles trigger a bug in IE5/Mac which will hide your background images altogether.

By default, the image will be placed at the top left corner of the element, and will be tiled (repeated). It will also scroll with the document. These are the default settings, but you can adjust all these settings with specific properties:

Here is a basic example of a background image applied to the <body> element:

body {
  margin: 0;
  padding: 0;
  background-image: url(images/dw-star.jpg);
}

The above code will tile the star image, starting from the top left corner of the body and continuing until the end of the line is reached. Then a new line will be tiled underneath, and so on until the whole body element is completely filled.

Note that the image doesn’t wrap at the end of each line—a new complete image will begin on the next line. There is also no way to adjust the spacing of the tiling (apart from adding space to the image itself).

Tiled star image

Placing a background image will have no effect on the size of the element, so you must ensure that there is enough height and width for the image to be displayed, or enough content to stretch the container.

background-image: none;—I think you can guess what this one does—it simply ensures that no image is displayed behind that element.

background-image: inherit;—To inherit the background image from a parent, you can use the value inherit, although it would be rare to use this. It results in images being re-tiled on the child element, and overlaying the parent’s background image—potentially very messy, as the images would not be perfectly aligned.

background-repeat

Possible values: repeat | repeat-x | repeat-y | no-repeat | inherit

This property allows you to define the direction in which the background image is repeated, or to prevent repeating altogether.

background-repeat: repeat;—The default value repeats the image along both the horizontal and vertical axis. (This doesn’t mean that the image is only repeated from right to left and top to bottom, but that the image is repeated along both axes, in both directions, until the whole area is tiled as shown in image 1 above.)

background-repeat: repeat-x;—When you set the value to repeat-x, the image will only be repeated horizontally. It is repeated in both horizontal directions until the whole row is tiled. The default starting position is the top left, but this can be changed—see background-position below.

Image repeated along the x-axis only

As you can see in the above image, only the x-axis (horizontal) is filled by our star image.

background-repeat: repeat-y;—This has the opposite effect of repeat-x—instead of repeating horizontally, the image will be repeated in the vertical direction only. As before, the image will be tiled up and down the vertical axis until the whole column is filled.

Image repeated along the y-axis only

background-repeat: no-repeat;—This prevents tiling of the image. The image is placed at the specified background-position—if no position is provided, then that will default to the top left of the element.

Image with no-repeat

background-repeat: inherit;—Causes an element to inherit the background-repeat property from its parent, and is not something that you would normally need to use.

background-position

Possible values: fixed length units (e.g. pixels) | percentage units | keywords

When you place a background image, you can specify its starting position in a number of ways—the simplest is to specify the exact position in pixels.

background-position: 100px 200px;—This will place the image’s top left corner 100px from the left edge of the element and 200px down from the top of the element—the position is always given as horizontal and then vertical. If only one length value is used, it is assumed to be for the horizontal position only—the vertical position defaults to fifty percent.

When used in conjunction with a repeating background (see the images above), the position specified is the position at which the image will be placed to start with—it is then repeated along the horizontal and/or vertical axes, depending on the type of background-repeat that has been set. The image will be repeated in both directions along each axis.

background-position: 50% 100%;—When using percentages to position a background image, things are handled a little differently. The percentage measurement not only refers to the position within the element itself but it also refers to that specific point in the image. If you were to set background-position: 50% 100%, the 50% horizontal position of the image (the exact center, in other words) would be aligned with the 50% position of the element, and the 100% vertical position of the image—its bottom edge—is aligned with the 100% vertical position of the element (i.e. its bottom edge).

It may be easier to explain by comparing background-position: 50% 50% to the equivalent if you were using absolute positioning. If you specified position: absolute with left: 50% and top: 50%, this would move the element’s top left corner into the dead center of the parent—the element itself wouldn’t be centered, it would be in the bottom right quadrant of its parent.

However, when percentage is used in the background-position property, it doesn’t refer to the top left of the element—it refers to the corresponding percentage part of the image—so background-position: 50% 50% would leave the image perfectly centered in its parent element.

Background position 50% 50%

The lower foreground image has been placed at top: 50% and left: 50% and that aligns the top left corner of the image to the exact center of the element. The top background image is placed at 50% 50% and, as you can see, the center of the image is placed in the exact center of the container.

(It’s a shame that there isn’t such a neat method for foreground images or block elements.)

As you will have no doubt worked out by now, using background-position: 100% 100%; would place the 100% position of the image (the bottom right corner) into the 100% position of the element (its bottom right corner), allowing for the child to fit snugly into the corner of the parent.

You can also mix percentages and pixels if needed:

background-position: 50% 200px;

It is also now permissible to mix keywords (see below) with percentage or pixel values (this was changed in CSS2.1 and was previously not allowed). I still advise against mixing them, though, because only modern browsers support this—there is no real benefit, as you can simply use the equivalent percentage measurement instead.

Keywords

There are also a number of keywords that you can use to position your background image—for the horizontal position you can use left, center, or right, and for the vertical position you can choose from top, center, or bottom.

To position an image at the top left of a page, you can therefore use:

background-position: left top;

The full list is as follows.

background-position: left top;    /* same as 0% 0% */
background-position: left center;  /* same as 0% 50% */
background-position: left bottom;  /* same as 0% 100% */

background-position: right top;    /* same as 100% 0% */
background-position: right center;  /* same as 100% 50% */
background-position: right bottom;  /* same as 100% 100% */

background-position: center top;   /* same as 50% 0% */
background-position: center center;  /* same as 50% 50% */
background-position: center bottom;  /* same as 50% 100% */

Unlike length units, you don’t have to keep the keywords in the strict order of horizontal and vertical. You can therefore specify something like background-position: top left; instead of @background-position: left top; .

If you use only one keyword instead of two, then the following will apply:

background-position: top;  /* same as 50% 0% */
background-position: left;  /* same as 0% 50% */
background-position: center;  /* same as 50% 50% */
background-position: right;  /* same as 100% 50% */
background-position: bottom;  /* same as 50% 100% */

background-attachment

Possible values: scroll | fixed | inherit

background-attachment: scroll;—The background-attachment property will determine whether the background image scrolls with the document or remains fixed to the viewing area. The default state is set to scroll, which means that as the document scrolls up or down, the image scrolls along with the document.

(The only time the image won’t scroll is if it is set inside a container that has overflow: auto set—the image will not scroll within that container, but will scroll with the main document. The content in the container itself will scroll over the image while the image will remain stationary and visible in that container. IE6 and IE7 differ on this aspect and will scroll the image inside that container. I will go into more detail below when explaining the fixed value, as there is information pertinent to both fixed and scroll values.)

background-attachment: fixed;—Using the fixed value will fix an image in position in the document so that even if the document scrolls up or down, the image will not move at all, and will remain at its original position (relative to the viewport). If you therefore place an image in the <body> background at 50% 50%, and use the fixed value, the image will remain pinned to the center of the viewport—even if the document itself scrolls all the way up or down. This is quite useful if you want to set an image as a background and have it always viewable, no matter how much content has been scrolled up or down.

Unfortunately, the fixed value when used on elements other than the <body> is a little more complicated in usage, and the concept may be a little hard to grasp at first.

The basic principle—and main cause of confusion—is that a fixed background image is always placed in relation to the viewport, and not in relation to the element it resides in.

Think about this for a minute and let the idea sink in.

(NB: It is worth mentioning at this stage that the following explanation does not apply to IE6 and older, as it gets the specs completely wrong on this issue, and will be explained later. IE7, though, does follow the correct format as explained below.)

If you have an element that is centered in the page, and you specify a background-position of 10px 10px expecting the image to be fixed 10px down from that element’s top left corner—you would be wrong. The 10px 10px position still refers to the viewport—the image will be placed 10px from the top left corner of the viewport, which could be miles away from the element you placed it in! It is very likely that the image will appear to be missing, as it will only appear when the element it resides in happens to be at the same position in the viewport as the position specified in the background position.

Whew! What did I just say?

Let’s have a look at an example that should clarify the issue. I am going to place an absolute element 100px from the top left corner of the page, and apply background-image: fixed; at the 10px 10px position as follows:

#outer {
  position: absolute;
  left: 50px;
  top: 100px;
  width: 200px;
  height: 200px;
  background: url(images/dw-star.jpg) no-repeat fixed 10px 10px;
  border: 1px solid red;
}

The result of the above code (in Firefox 2.0) can be seen below:

Where''s the image gone

The image appears to be missing—as I said it would. Obviously, the image isn’t really missing, but as it has been placed at 10px 10px relative to the viewport, it will only show when the element (bordered in red in the image above) sits at the same position as 10px 10px. To make things clearer, let’s move the red bordered box to 30px from the top of the screen instead:

#outer {
  position: absolute;
  left: 50px;
  top: 30px;
  width: 200px;
  height: 200px;
  background: url(images/dw-star.jpg) no-repeat fixed 10px 10px;
  border: 1px solid red;
}

star image found

A-ha! Now we can see some of the image because our red box overlaps the background position where our image has been placed. And if we moved the red box to position 10px 10px, all of the image would be visible.

How is this useful, and what about IE6?

Now that you know how to find your fixed background image, you might be wondering, “Why and how is this useful?”

First we need to explore how IE6 (and older) behaves—and for this, we need another example:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <title>Untitled Document</title>
    <style type="text/css">
      * {margin:0;padding:0}
      #outer {
        position: absolute; 
        left: 100px; 
        top: 100px; 
        width: 400px; 
        height: 300px; 
        background: url(images/volcano-1.jpg) no-repeat fixed 10px 10px; 
        border: 1px solid red; 
      }
    </style>
  </head>
  <body>
    <div id="outer">
      <p>test</p>
    </div>
  </body>
</html>

The image is placed inside #outer and its background-attachment is set to fixed. The position of 10px 10px will place the image in the top left corner of the viewport (and not #outer, as you’ll know if you’ve been paying attention).

View the following page in IE6 and then Firefox (or another modern browser):

Fixed positioning example

In case you don’t have either browser, here are some screenshots in Firefox and IE6 to compare the differences:

Firefox fixed positioning

IE6 Fixed positioning

As you can see, in Firefox, only that part of the image that coincides with the position of #outer is revealed. The rest of the image is hidden.

IE6 and older, however, get this all wrong and place the image in the top left (10px 10px) of #outer rather than the viewport. The image will, though, be fixed in that position, and should content scroll inside that red container, then the image will remain fixed within that position and the content will scroll over the top. However, the image will not remain fixed should the document scroll—the red box, along with the image, will scroll off the page. In fact, the behavior we experience when using fixed in IE6 is the same that you would get in Firefox if you had used the default background scroll instead of fixed. As if it weren’t complicated enough already!

In Firefox, an image placed in the background of an element using scroll (the default) will always keep that image visible in that container. If overflow: auto has been set on the container, and scrollbars activated, the image will not scroll at all—only the foreground content will scroll, leaving the image in view at all times. Using scroll in IE6, however, will allow the image to scroll with the content and disappear along with the content in that container.

Using the following code, we can trigger these two distinct behaviors in our favorite browsers:

background: url(images/dw-star.jpg) no-repeat scroll 10px 10px;

firefox and IE comparisons

To make IE6 behave like Firefox when scroll has been applied, you would need to use the value fixed instead (by using a hack or conditional comment to target IE6 only)—but there is no way to make IE6 support the fixed value in the correct manner as demonstrated by Firefox.

I mentioned above that IE7 now supports the fixed value, but as a consequence, this has introduced an interesting behavior when scroll is used; IE7 behaves the same as IE6 and will allow the image to scroll within that container (unlike other browsers that keep the image visible in the container even when foreground content scrolls), so in IE7 there is no way to have the image remain visible within an overflow container (such as in the Firefox example in the image above). If you use fixed, then the image is fixed in relation to the viewport—but if you use scroll then the image scrolls within that container. So IE7 has implemented background-attachment: fixed correctly but has failed to implemented scroll correctly.

There are still more combinations of behaviors to talk about when using fixed—what happens to a fixed image when the document scrolls and the element that contains the fixed image also scrolls?

Fixed position comparisons

I have scrolled both the container and the document and—as you can see—the fixed image in Firefox has not moved at all. The parent container slides over the image, revealing bits of the image as it passes over, but the image never moves at all; only when the container is over the image does that image become visible. IE7 behaves exactly the same in this respect.

IE6, on the other hand, keeps the image fixed within the parent container—but once the document scrolls, the whole lot just disappears upwards.

The logical conclusion to all this is that you can really only use background-attachment: fixed cross-browser when you apply it to the <body> element, as that is the only time that IE6 gets it right. Of course, now that you know the limitations, you can always use conditional comments to give IE the basic version, and let good browsers have the advanced version.

Inherit

When you use background: inherit, the element will inherit the background properties from its parent. This is seldom a good idea—the default value for an element’s background is transparent, and therefore the parents background will already be visible in the child element—there is no need to specify inherit.

IE6 and Safari 2.0 also do have a small bug associated with background: inherit: Background inherit doesn’t reset the background color

Shorthand

The background property in CSS is a shorthand element, and can be used to set several background styles for an element at the same time. You may have noticed in some of the examples above that I used the shorthand version to define all the background properties in one go.

Using CSS shorthand can save a lot of code and time, and I use shorthand wherever possible. Take the following code for instance:

#test {
  background-color: #000; 
  background-image: url(image-name.jpg); 
  background-position: 10px 10px; 
  background-repeat: no-repeat; 
  background-attachment: fixed; 
}

This could be reduced to one line of code:

#test {
  background: #000 url(image-name.jpg) no-repeat fixed 10px 10px; 
}

That’s quite a saving on code, and is well worth doing.

Something to be aware of when using shorthand (and the same is true of all shorthand elements) is that any properties that you don’t set in the shorthand rule will be reset to their defaults. Therefore if you had a rule like this:

#test {
  background-color: red; 
  background: url(image-name.jpg); 
}

The red color would not be implemented because the shorthand style that follows it will reset the color to the default of transparent, because it has not been specified explicitly. The same applies to all the other properties not being set in that rule—all properties not specified will revert to their initial defaults and override any previously set.

It doesn’t matter what order you set most of the background properties in shorthand notation, as the browser will still recognize them, but the usual format is as follows:

background: #000 url(image-name.jpg) no-repeat fixed 10px 10px;

(Of course, it does matter the order in which you specify the background-position coordinates, because the unit will be applied in the order of horizontal then vertical. See the entry on background-position which goes into more detail on this above.)

Summary

We’ve covered most aspects of the background property and associated values, and in general day-to-day to usage these CSS properties can give you a lot of control over the look-and-feel of the elements used in your design. As you can see, the background property is very versatile. You can do some very clever things with it, and—if you have a little imagination—you can produce some stunning effects.

Further Reading

Got something to say?

Share your comments  with other professionals (15 comments)

Related Topics: Web Design, CSS, Basics

 

Paul O'Brien, when he's not working, can usually be found handing out advice in the CSS Forums at Sitepoint where he is an advisor. He works as a freelance Web Designer specialising in CSS layouts only.

Media Temple

via Ad Packs