DekGenius.com
Previous Section  < Day Day Up >  Next Section

9.3 Backgrounds

The background area of an element consists of all of the space behind the foreground out to the outer edge of the borders; thus, the content box and the padding are all part of an element's background, which and the borders are drawn on top of the background.

CSS lets you apply a solid color or create moderately sophisticated effects using background images, and its capabilities in this area far outstrip those of HTML.

9.3.1 Background Color

It's possible to declare a color for the background of an element, in a fashion very similar to setting the foreground color. For this, you use the property background-color, which accepts (unsurprisingly) any valid color or a keyword that makes the background transparent.

background-color


Values

<color> | transparent | inherit


Initial value

transparent


Applies to

all elements


Inherited

no


Computed value

as specified


If you want the color to extend out a little bit from the text in the element, simply add some padding to the mix, as illustrated in Figure 9-8:

p {background-color: gray; padding: 10px;}
Figure 9-8. Backgrounds and padding
figs/css2_0908.gif

You can set a background color for just about any element, from body all the way down to inline elements such as em and a. background-color is not inherited. Its default value is transparent, which makes sense: if an element doesn't have a defined color, then its background should be transparent so that the background of its ancestor elements will be visible.

One way to picture the inheritance situation is to imagine a clear plastic sign mounted to a textured wall. The wall is still visible through the sign, but this is not the background of the sign, it's the background of the wall (in CSS terms, anyway). Similarly, if you set the canvas to have a background, it can be seen through all of the elements in the document that don't have their own backgrounds. They don't inherit the background; it is visible through them. This may seem like an irrelevant distinction, but as you'll see in the section on background images, it's actually a critical difference.

Most of the time, you'll have no reason to use the keyword transparent since that's the default value. On occasion, though, it can be useful. Imagine that a user has set his browser to make all links have a white background. When you design your page, you set anchors to have a white foreground, and you don't want a background on those anchors. In order to make sure your design choice prevails, you would declare:

a {color: white; background-color: transparent;}

If you left out the background color, your white foreground would combine with the user's white background to yield totally unreadable links. This is an unlikely example, but it's still possible.

The potential combination of author and reader styles is the reason why a CSS validator will generate warnings such as, "You have no background-color with your color." It's trying to remind you that author-user color interaction can occur, and your rule has not taken this possibility into account. Warnings do not mean your styles are invalid: only errors prevent validation.


9.3.1.1 Historical issues

So, setting a background color is a pretty simple thing—except for one small warning: Navigator 4 gets the placement of background colors completely wrong. Instead of applying the background color to the entire content box and padding, the color appears only behind the text itself, as shown in Figure 9-9.

Figure 9-9. Navigator 4.x's incorrect behavior
figs/css2_0909.gif

Let me reiterate: this behavior is totally wrong. To counteract it, you must set a border on the element, which you can then set to be the same color as the background color of your document:

body {background: silver;}
p {background-color: gray; padding: 0.1px; border: 1px solid silver;}

Note that you must set a border-style for this technique to work. It doesn't matter whether you use that specific property or simply a value of the border property.

Of course, by doing this, you're setting a border on the element, and that border will show up in other user agents as well. To top things off, Navigator doesn't handle padding very well, so the previous example would result in a small amount of blank space between the content box and the borders. Thankfully, newer browsers don't suffer from such problems.

9.3.1.2 Special effects

Simply by combining color and background-color, you can create some useful effects:

h1 {color: white; background-color: rgb(20%,20%,20%);
  font-family: Arial, sans-serif;}

This example is shown in Figure 9-10.

Figure 9-10. A nifty effect for H1 elements
figs/css2_0910.gif

Of course, there are as many color combinations as there are colors, but I can't show all of them here—being stuck in a grayscale as we are. Still, I'll try to give you some idea of what you can do.

This style sheet is a little more complicated, as illustrated by Figure 9-11:

body {color: black; background-color: white;}
h1, h2 {color: yellow; background-color: rgb(0,51,0);}
p {color: #555;}
a:link {color: black; background-color: silver;}
a:visited {color: gray; background-color: white;}
Figure 9-11. The results of a more complicated style sheet
figs/css2_0911.gif

This is just the tiniest beginning of what's possible, of course. By all means, try some examples of your own!

9.3.2 Background Images

Having covered the basics of foreground and background colors, we turn now to the subject of background images. In HTML 3.2, it was possible to associate an image with the background of the document by using the BODY attribute BACKGROUND:

<BODY BACKGROUND="bg23.gif">

This caused a user agent to load the file bg23.gif and then "tile" it in the document background, repeating it in both the horizontal and vertical directions to fill up the entire background of the document. This effect can be duplicated in CSS, but CSS can do a great deal more than simple tiling of background images. We'll start with the basics and then work our way up.

9.3.2.1 Using an image

In order to get an image into the background in the first place, use the property background-image.

background-image


Values

<uri> | none | inherit


Initial value

none


Applies to

all elements


Inherited

no


Computed value

absolute URI


The default value of none means about what you'd expect: no image is placed in the background. If you want a background image, you must give this property a URL value:

body {background-image: url(bg23.gif);}

Due to the default values of other background properties, this will cause the image bg23.gif to be tiled in the document's background, as shown in Figure 9-12. As you'll discover shortly, though, tiling isn't the only option.

Figure 9-12. Applying a background image in CSS
figs/css2_0912.gif

It's usually a good idea to specify a background color to go along with your background image; we'll come back to that concept a little later in the chapter.


You can apply a background image to any element, block-level or inline. Most backgrounds are applied to body elements, of course, but there's no need to stop there:

p.starry {background-image: url(http://www.site.web/pix/stars.gif);
   color: white;}
a.grid {background-image: url(smallgrid.gif);}

<p class="starry">It's the end of autumn, which means the stars will be 
brighter than ever!  <a href="join.html" class="grid">Join us</a> for
a fabulous evening of planets, stars, nebulae, and more...

As you can see in Figure 9-13, you've applied a background to a single paragraph and no other part of the document. You can customize even further, such as placing background images on inline elements like hyperlinks, also depicted in Figure 9-13. Of course, if you want to be able to see the tiling pattern, the image will probably need to be pretty small. After all, individual letters aren't that large!

Figure 9-13. Applying background images to block and inline elements
figs/css2_0913.gif

There are a number of ways to employ specific background images. You might place an image in the background of strong elements in order to make them stand out more. You could fill in the background of headings with a wavy pattern or with little dots. You can even fill in the cells of tables with patterns to make them distinct from the rest of the page, as shown in Figure 9-14:

td.nav {background-image: url(darkgrid.gif);}
Figure 9-14. Setting a background image for a table cell
figs/css2_0914.gif

You could even, in theory, apply images to the background of replaced elements such as textareas and select lists, although not every user agent is good at handling that sort of thing.

Just like background-color, background-image is not inherited—in fact, none of the background properties are inherited. Remember also that when specifying the URL of a background image, it falls under the usual restrictions and caveats for url values: a relative URL should be interpreted with respect to the style sheet, but Navigator 4.x doesn't do this correctly, so absolute URLs may be a better answer.

9.3.2.2 Why backgrounds aren't inherited

Earlier, I specifically noted that backgrounds are not inherited. Background images demonstrate why inherited backgrounds would be a bad thing. Imagine a situation where backgrounds were inherited, and you applied a background image to the body. That image would be used for the background of every element in the document, with each element doing its own tiling, as shown in Figure 9-15.

Figure 9-15. What inherited backgrounds would do to layout
figs/css2_0915.gif

Note how the pattern restarted at the top left of every element, including the links. This isn't what most authors would want, and so this is why background properties are not inherited. If you do want this particular effect for some reason, you can make it happen with a rule like this:

* {background-image: url(yinyang.gif);}

Alternatively, you could use the value inherit like this:

body {background-image: url(yinyang.gif);}
* {background-image: inherit;}
9.3.2.3 Good background practices

Images are laid on top of whatever background color you specify. If you're completely tiling GIF, JPEG, or other opaque image types, this fact doesn't really make a difference, since a fully tiled image will fill up the document background, leaving nowhere for the color to "peek through," so to speak. However, image formats with an alpha channel, such as PNG, can be partially or wholly transparent, and this will cause the image to be combined with the background color. In addition, if the image fails to load for some reason, then the user agent will use the background color specified in place of the image. Consider how the "starry paragraph" example would look if the background image failed to load, as in Figure 9-16.

Figure 9-16. The consequences of a missing background image
figs/css2_0916.gif

Figure 9-16 demonstrates why it's always a good idea to specify a background color when using a background image, so that you'll at least get a legible result:

p.starry {background-image: url(http://www.site.web/pix/stars.gif);
   background-color: black; color: white;}
a.grid {background-image: url(smallgrid.gif);}

<p class="starry">It's the end of autumn, which means the stars will be 
brighter than ever!  <a href="join.html" class="grid">Join us</a> for
a fabulous evening of planets, stars, nebulae, and more...

This will fill in a flat black background if the "starry" image can't be rendered for some reason. Besides, if you have the image do something other than fully tile across the entire background of the document, you'll need a color to cover the parts that the image doesn't. Speaking of which....

9.3.3 Repeats with Direction

In the old days, if you wanted some kind of "sidebar" background, you had to create a very short, but incredibly wide, image to place in the background. At one time, a favorite size for these images was 10 pixels tall by 1,500 pixels wide. Most of that image would be blank space, of course; only the left 100 or so pixels contain the "sidebar" image. The rest of the image was basically wasted.

Wouldn't it be much more efficient to create a sidebar image that's 10 pixels tall and 100 pixels wide, with no wasted blank space, and then repeat it only in the vertical direction? This would certainly make your design job a little easier, and your users' download times a lot faster. Enter background-repeat.

background-repeat


Values

repeat | repeat-x | repeat-y | no-repeat | inherit


Initial value

no-repeat


Applies to

all elements


Inherited

no


Computed value

as specified


As you might guess, repeat causes the image to tile in both the horizontal and vertical directions, just as background images have always done in the past. repeat-x and repeat-y cause the image to be repeated in the horizontal or vertical directions, respectively, and no-repeat prevents the image from tiling in any direction.

By default, the background image will start from the top left corner of an element. (We'll see how to change this later in the chapter.) Therefore, the following rules will have the effect shown in Figure 9-17:

body {background-image: url(yinyang.gif); 
   background-repeat: repeat-y;}
Figure 9-17. Tiling the background image vertically
figs/css2_0917.gif

(I've left out a background color in order to keep the rule short, but remember to include a background color any time you have a background image.)

Let's assume, though, that you want the image to repeat across the top of the document. Rather than creating a special image with a whole lot of blank space underneath, you can simply make a small change to your rule:

body {background-image: url(yinyang.gif); 
   background-repeat: repeat-y;}

As Figure 9-18 shows, the image is simply repeated along the x-axis (that is, horizontally) from its starting position—in this case, the top left corner of the browser window.

Figure 9-18. Tiling horizontally
figs/css2_0918.gif

Finally, you may not want to repeat the background image at all. In this case, you use the value no-repeat:

body {background-image: url(yinyang.gif); 
   background-repeat: no-repeat;}

This value may not seem terribly useful, given that the above declaration would just drop a small image into the top left corner of the document, but let's try it again with a much bigger symbol, as shown in Figure 9-19:

body {background-image: url(bigyinyang.gif); 
   background-repeat: no-repeat;}
Figure 9-19. Placing a single large background image
figs/css2_0919.gif

The ability to control the repeat direction dramatically expands the range of possible effects. For example, let's say you want a triple border on the left side of each h1 element in your document. You can take that concept further and decide to set a wavy border along the top of each h2 element. The image is colored in such a way that it blends with the background color and produces the wavy effect shown in Figure 9-20:

h1 {background-image: url(triplebor.gif); background-repeat: repeat-y;}
h2 {background-image: url(wavybord.gif); background-repeat: repeat-x;
    background-color: #CCC;}
Figure 9-20. Bordering elements with background images
figs/css2_0920.gif

Simply by choosing the appropriate image for the job, and employing it in some creative ways, you can set up some very interesting effects. And that isn't the end of what's possible. Now that you know how to constrain a background image's repetition, how about moving it around in the background area?

9.3.4 Background Positioning

Thanks to background-repeat, it's possible to place a large image in the background of a document and then keep it from repeating. Let's add to that and actually change the image's position in the background.

background-position


Values

[[<percentage> | <length> | left | center | right] [<percentage>] | <length> | top | center | bottom]?] || [[left | center | right] || [top | center | bottom]] | inherit


Initial value

0% 0%


Applies to

block-level and replaced elements


Inherited

no


Percentages:

refer to the corresponding point on both the element and the origin image (see explanation in Section 9.3.4.2 later in this chapter)


Computed value

the absolute length offsets, if <length> is specified; otherwise, percentage values


For example, you could center a background image in the body element, with the result depicted in Figure 9-21:

body {background-image: url(bigyinyang.gif); 
   background-repeat: no-repeat;
   background-position: center;}
Figure 9-21. Centering a single background image
figs/css2_0921.gif

You've actually placed a single image in the background and then prevented it from being repeated with the value no-repeat. Every background that includes an image starts with a single image that is then repeated (or not) according to the value of background-repeat. This starting point is called the origin image.

The placement of the origin image is accomplished with background-position, and there are several ways to supply values for this property. First off, there are the keywords top, bottom, left, right, and center. Usually, these appear in pairs, but (as the previous example shows) this is not always true. Then there are length values, such as 50px or 2cm, and finally, percentage values. Each type of value has a slightly different effect on the placement of the background image.

I should mention one more thing, and that's the context in which background images are placed. CSS2 and CSS2.1 state that background-position is used to place the origin image with respect to the padding edge of the element. In other words, the image placement context is the inner border edge, even though the background area extends to the outer border edge. Not every browser places images properly: some place the origin image with respect to the outer border edge instead of the inner border edge. In any situation where there is no border, the effect is identical either way.

For those interested in how CSS has changed over the years, CSS1 defined placement relative to the content area.


Despite image placement context, a fully tiled background image would indeed fill in the border area's background because a tiled image goes in all four directions. We'll talk about this in more detail later. First, you need to find out how the origin image can be positioned within the element.

9.3.4.1 Keywords

The image placement keywords are easiest to understand. They have the effects you'd expect from their names; for example, top right would cause the origin image to be placed in the top right corner of the element's padding area. Let's go back to the small yin-yang symbol:

p {background-image: url(yinyang.gif); 
   background-repeat: no-repeat;
   background-position: top right;}

This will place a nonrepeated origin image in the top right corner of each paragraph's padding. Incidentally, the result, shown in Figure 9-22, would be exactly the same if the position were declared as right top. Position keywords can appear in any order (according to the specification), as long as there are no more than two of them—one for the horizontal and one for the vertical.

Figure 9-22. Placing the background image in the top right corner of paragraphs
figs/css2_0922.gif

The Netscape 6.x family has a bug that causes it to ignore a rule if the background-position keywords are in a particular order. To avoid tripping the bug, make sure your keywords give the horizontal placement first and then the vertical. Thus, write left center instead of center left.


If only one keyword appears, then the other is assumed to be center. Table 9-1 shows equivalent keyword statements.

Table 9-1. Position keyword equivalents

Single keyword

Equivalent keywords

center

center center

top

top centercenter top

bottom

bottom centercenter bottom

right

center rightright center

left

center leftleft center

So if you want an image to appear in the top center of every paragraph, you need only declare:

p {background-image: url(yinyang.gif); 
   background-repeat: no-repeat;
   background-position: top;}
9.3.4.2 Percentage values

Percentage values are closely related to the keywords, although they behave in a more sophisticated way. Let's say that you want to center an origin image within its element by using percentage values. That's easy enough:

p {background-image: url(bigyinyang.gif); 
   background-repeat: no-repeat;
   background-position: 50% 50%;}

This causes the origin image to be placed such that its center is aligned with the center of its element. In other words, the percentage values apply to both the element and the origin image.

In order to understand what I mean, let's examine the process in closer detail. When you center an origin image in an element, the point in the image that can be described as 50% 50% (the center) is lined up with the point in the element that can be described the same way. If the image is placed at 0% 0%, its top left corner is placed in the top left corner of the padding area of the element. 100% 100% causes the origin image's bottom right corner to go into the bottom right corner of the padding area:

p {background-image: url(oransqr.gif); 
   background-repeat: no-repeat;
   padding: 5px;  border: 1px dotted gray;}
p.c1 {background-position: 0% 0%;}
p.c2 {background-position: 50% 50%;}
p.c3 {background-position: 100% 100%;}
p.c4 {background-position: 0% 100%;}
p.c5 {background-position: 100% 0%;}

Figure 9-23 illustrates these rules.

Figure 9-23. Various percentage positions
figs/css2_0923.gif

Thus, if you want to place a single origin image a third of the way across the element and two-thirds of the way down, your declaration would be:

p {background-image: url(bigyinyang.gif); 
   background-repeat: no-repeat;
   background-position: 33% 66%;}

With these rules, the point in the origin image that is one-third across and two-thirds down from the top left corner of the image will be aligned with the point that is farthest from the top left corner of the containing element. Note that the horizontal value always comes first with percentage values. If you were to switch the percentages in the preceding example, the image would be placed two-thirds of the way across the element and one-third of the way down.

If you supply only one percentage value, the single value supplied is taken to be the horizontal value, and the vertical is assumed to be 50%. This is similar to keywords, where if only one keyword is given, the other is assumed to be center. For example:

p {background-image: url(yinyang.gif); 
   background-repeat: no-repeat;
   background-position: 25%;}

The origin image is placed one-quarter of the way across the element's content area and padding area, and halfway down it, as depicted in Figure 9-24.

Figure 9-24. Declaring only one percentage value means the vertical position evaluates to 50%
figs/css2_0924.gif

Table 9-2 gives a breakdown of keyword and percentage equivalencies.

Table 9-2. Positional equivalents

Single keyword

Equivalent keywords

Equivalent percentages

center

center center

50% 50%50%

top

top centercenter top

50% 0%

bottom

bottom centercenter bottom

50% 100%

right

center rightright center

100% 50%100%

left

center leftleft center

0% 50%0%

 

top leftleft top

0% 0%

 

top rightright top

100% 0%

 

bottom rightright bottom

100% 100%

 

bottom leftleft bottom

0% 100%

In case you were wondering, the default values for background-position are 0% 0%, which is functionally the same as top left. This is why, unless you set different values for the position, background images always start tiling from the top left corner of the element's padding area.

9.3.4.3 Length values

Finally, we turn to length values for positioning. When you supply lengths for the position of the origin image, they are interpreted as offsets from the top left corner of the element's padding area. The offset point is the top left corner of the origin image; thus, if you set the values 20px 30px, the top left corner of the origin image will be 20 pixels to the right of, and 30 pixels below, the top left corner of the element's padding area, as shown in Figure 9-25:

p {background-image: url(yinyang.gif); 
   background-repeat: no-repeat;
   background-position: 20px 30px;
   border: 1px dotted gray;}
Figure 9-25. Offsetting the background image using length measures
figs/css2_0925.gif

This is quite different than percentage values because the offset is simply from one top left corner to another. In other words, the top left corner of the origin image lines up with the point specified in the background-position declaration. You can combine length and percentage values, though, to get a sort of "best of both worlds" effect. Let's say you need to have a background image that is all the way to the right side of an element and 10 pixels down from the top, as illustrated in Figure 9-26. As always, the horizontal value comes first:

p {background-image: url(bg23.gif); 
   background-repeat: no-repeat;
   background-position: 100% 10px;
   border: 1px dotted gray;}
Figure 9-26. Mixing percentages and length values
figs/css2_0926.gif

In versions of CSS prior to 2.1, you could not mix keywords with other values. Thus, top 75% was not valid, and if you used a keyword, you were stuck using only keywords. CSS2.1 changed to allow this in order to make authoring easier and also because typical browsers had already allowed it.


If you're using lengths or percentages, you can use negative values to pull the origin image outside of the element's background area. Consider the example with the very large yin-yang symbol for a background. At one point, you centered it, but what if you only want part of it visible in the top left corner of the element's padding area? No problem, at least in theory.

First, assume that the origin image is 300 pixels tall by 300 pixels wide. Then, assume that only the bottom right third of it should be visible. You can get the desired effect (shown in Figure 9-27) like this:

p {background-image: url(bigyinyang.gif); 
   background-repeat: no-repeat;
   background-position: -200px -200px;
   border: 1px dotted gray;}
Figure 9-27. Using negative length values to position the origin image
figs/css2_0927.gif

Or, say you want just the right half of it to be visible and centered within the element:

p {background-image: url(bigyinyang.gif); 
   background-repeat: no-repeat;
   background-position: -150px 50%;
   border: 1px dotted gray;}

Negative percentages are also possible in theory, although there are two issues involved. The first is the limitations of user agents, which may not recognize negative values for background-position.

The other is that negative percentages are somewhat interesting to calculate. The origin image and the element are likely to be very different sizes, for one thing, and that can lead to unexpected effects. Consider, for example, the situation created by the following rule and illustrated in Figure 9-28:

p {background-image: url(pix/bigyinyang.gif); 
   background-repeat: no-repeat;
   background-position: -10% -10%;
   border: 1px dotted gray;
   width: 500px;}
Figure 9-28. Varying effects of negative percentage values
figs/css2_0928.gif

The rule calls for the point outside the origin image defined by -10% -10% to be aligned with a similar point for each paragraph. The image is 300 x 300 pixels, so we know its alignment point can be described as 30 pixels above the top of the image, and 30 pixels to the left of its left edge (effectively -30px and -30px). The paragraph elements are all the same width (500px), so the horizontal alignment point is 50 pixels to the left of the left edge of their padding areas. This means that each origin image's left edge will be 20 pixels to the left of the left padding edge of the paragraphs. This is because the -30px alignment point of the images lines up with the -50px point for the paragraphs. The difference between the two is 20 pixels.

The paragraphs are of differing heights, however, so the vertical alignment point changes for each paragraph. If a paragraph is 300 pixels high, to pick a semi-random example, then the top of the origin image will line up exactly with the top of the element's padding area, because both will have vertical alignment points of -30px. If a paragraph is 50 pixels tall, then its alignment point would be -5px and the top of the origin image will actually be 25 pixels below the top of the padding area.

The same issues can arise with positive percentage values—imagine what would happen if you aligned an origin image to the bottom of an element shorter than the image—so this isn't to say that you shouldn't use negative values. It's just a reminder that there are, as always, issues to consider.

Throughout this section, every example has had a repeat value of no-repeat. The reason for this is simple: with only a single background image, it's much easier to see how positioning affects the placement of the first background image. You don't have to prevent the background image from repeating, though:

p {background-image: url(bigyinyang.gif); 
   background-position: -150px 50%;
   border: 1px dotted gray;}

So, with the background repeating, you can see from Figure 9-29 that the tiling pattern starts with the position specified by background-position.

Figure 9-29. Use of the background-position property sets the origin of the tiling pattern
figs/css2_0929.gif

This illustrates once more the concept of the origin image, which is very important to understanding the next section.

9.3.5 Repeats with Direction (Revisited)

In the previous section on repetition, we explored the values repeat-x, repeat-y, and repeat, and how they affect the tiling of background images. In each case, however, the tiling pattern always started from the top left corner of the containing element (e.g., p). This isn't a requirement, of course; as we've seen, the default values for background-position are 0% 0%. So, unless you change the position of the origin image, that's where the tiling starts. Now that you know how to change the position of the origin image, though, you need to figure out how user agents will handle the situation.

It will be easier to show an example and then explain it. Consider the following markup, which is illustrated in Figure 9-30:

p {background-image: url(yinyang.gif); 
   background-position: center;
   border: 1px dotted gray;}
p.c1 {background-repeat: repeat-y;}
p.c2 {background-repeat: repeat-x;}
Figure 9-30. Centering the origin image and repeating it
figs/css2_0930.gif

So there you have it: stripes running through the center of the elements. It may look wrong, but it isn't.

The examples shown in Figure 9-30 are correct because the origin image has been placed in the center of the first p element and then tiled along the y-axis in both directions—in other words, both up and down. For the second paragraph, the images are repeated to the right and left.

Therefore, setting a large image in the center of the p and then letting it fully repeat will cause it to tile in all four directions: up, down, left, and right. The only difference background-position makes is in where the tiling starts. Figure 9-31 shows the difference between tiling from the center of an element and from its top left corner.

Figure 9-31. The difference between centering a repeat and starting it from the top left
figs/css2_0931.gif

Note the differences along the edges of the element. When the background repeats from the center, as in the first paragraph, the grid of yin-yang symbols is centered within the element, resulting in consistent "clipping" along the edges. In the second paragraph, the tiling begins at the top left corner of the padding area, so the clipping is not consistent. The variations may seem subtle, but it's likely that you'll need to use both approaches at some point in your design career.

In case you're wondering, there is no way to control the repeat any more than we've already discussed. There is no repeat-left, for example, although such a value could be added in some future version of CSS. For now, you get full tiling, horizontal tiling, vertical tiling, or no tiling at all.

9.3.6 Getting Attached

So, now you can place the origin image for the background anywhere in the background of an element, and you can control (to a degree) how it tiles. As you may already have realized, though, placing an image in the center of the body element may mean, given a sufficiently long document, that the background image won't be initially visible to the reader. After all, a browser provides only a window onto the document. If the document is too long to be displayed in the window, then the user can scroll back and forth through the document. The center could be two or three "screens" below the beginning of the document, or just far enough down to push most of the origin image beyond the bottom of the browser window.

Furthermore, even if you assume that the origin image is initially visible, it always scrolls with the document—it'll vanish every time a user scrolls beyond the image's location. Never fear: there is a way to prevent this scrolling.

background-attachment


Values

scroll | fixed | inherit


Initial value

scroll


Applies to

all elements


Inherited

no


Computed value

as specified


Using the property background-attachment, you can declare the origin image to be fixed with respect to the viewing area and therefore immune to the effects of scrolling:

body {background-image: url(bigyinyang.gif); 
   background-repeat: no-repeat;
   background-position: center;
   background-attachment: fixed;}

Doing this has two immediate effects, as you can see from Figure 9-32. The first is that the origin image does not scroll along with the document. The second is that the placement of the origin image is determined by the size of the viewing area, not the size (or placement within the viewing area) of the element that contains it.

Figure 9-32. Nailing the background in place
figs/css2_0932.gif

In a web browser, the viewing area can change as the user resizes the browser's window. This will cause the background's origin image to shift position as the window changes size. Figure 9-33 depicts several views of the same document. So, in a certain sense, the image isn't fixed in place, but it will remain fixed as long as the viewing area isn't resized.

Figure 9-33. The centering continues to hold
figs/css2_0933.gif

There is only one other value for background-attachment, and that's the default value scroll. As you'd expect, this causes the background to scroll along with the rest of the document when viewed in a web browser, and it doesn't necessarily change the origin image's position as the window is resized. If the document width is fixed (perhaps by assigning an explicit width to the body element), then resizing the viewing area won't affect the placement of a scroll-attachment origin image at all.

9.3.6.1 Interesting effects

In technical terms, when a background image has been fixed, it is positioned with respect to the viewing area, not the element that contains it. However, the background will be visible only within its containing element. This leads to a rather interesting consequence.

Let's say you have a document with a tiled background that actually looks like it's tiled, and an h1 element with the same pattern, only in a different color. Both the body and h1 elements are set to have fixed backgrounds, resulting in something like Figure 9-34:

body {background-image: url(grid1.gif); background-repeat: repeat;
   background-attachment: fixed;}
h1 {background-image: url(grid2.gif); background-repeat: repeat;
   background-attachment: fixed;}
Figure 9-34. Perfect alignment of backgrounds
figs/css2_0934.gif

How is this perfect alignment possible? Remember, when a background is fixed, the origin element is positioned with respect to the viewport. Thus, both background patterns begin tiling from the top left corner of the viewport, not the individual elements. For the body, you can see the entire repeat pattern. For the h1, however, the only place you can see its background is in the padding and content of the h1 itself. Since both background images are the same size, and they have precisely the same origin, they appear to "line up," as shown in Figure 9-34.

This capability can be used to create some very sophisticated effects. One of the most famous examples is the "complexspiral distorted" demonstration (http://www.meyerweb.com/eric/css/edge/complexspiral/glassy.html), which is shown in Figure 9-35.

Figure 9-35. The complexspiral distorted
figs/css2_0935.gif

The visual effects are caused by assigning different fixed-attachment background images to non-body elements. The entire demo is driven by one HTML document, four JPEG images, and a style sheet. Because all four images are positioned in the top-left corner of the browser window, but are visible only where they intersect with their elements, the images effectively interleave to create the illusion of translucent rippled glass.

Internet Explorer for Windows, up through Version 6, does not properly handle fixed-attachment backgrounds on non-body elements. In other words, you get the expected effect for a fixed body background, but not for other elements. This wrecks the alignment effects seen in Figure 9-34 and Figure 9-35.


It is also the case that in paged media, such as printouts, every page generates its own viewport. Therefore, a fixed-attachment background should appear on every page of the printout. This could be used for effects such as watermarking all the pages in a document, for example. The problems are twofold: there is no way to force background images to print with CSS, and not all browsers properly handle the printing of fixed-attachment backgrounds.

9.3.7 Bringing It All Together

Just as with the font properties, the background properties can all be brought together in a single shorthand property: background. This property can take a single value from each of the other background properties, in literally any order.

background


Values

[ <background-color> || <background-image> || <background-repeat> || <background-attachment> || <background-position> ] | inherit


Initial value

refer to individual properties


Applies to

all elements


Inherited

no


Percentages

values are allowed for <background-position>


Computed value

see individual properties


Therefore, the following statements are all equivalent and will have the effect shown in Figure 9-36:

body {background-color: white; background-image: url(yinyang.gif);
   background-position: top left; background-repeat: repeat-y;
   background-attachment: fixed;}
body {background: white url(yinyang.gif) top left repeat-y fixed;}
body {background: fixed url(yinyang.gif) white top left repeat-y;}
body {background: url(yinyang.gif) white repeat-y fixed top left;}
Figure 9-36. Using shorthand
figs/css2_0936.gif

Actually, there is one slight restriction to how the values are ordered in background, which is that if you have two values for background-position, they must appear together and, if they are length or percentage values, they must be in the order horizontal first, then vertical. This probably isn't a surprise, but it is important to remember.

As is the case for shorthand properties, if you leave out any values, the defaults for the relevant properties are filled in automatically. Thus, the following two are equivalent:

body {background: white url(yinyang.gif;}
body {background: white url(yinyang.gif) top left repeat scroll;}

Even better, there are no required values for background—as long as you have at least one value present, you can omit all the rest. Therefore, it's possible to set just the background color using the shorthand property, which is a very common practice:

body {background: white;}

This is perfectly legal, and in some ways preferred, given the reduced number of keystrokes. In addition, it has the effect of setting all of the other background properties to their defaults, which means that background-image will be set to none. This helps ensure readability by preventing other rules (in, for example, the reader style sheet) from setting an image in the background.

Any of the following rules are also legal, as illustrated in Figure 9-37:

body {background: url(yinyang.gif) bottom left repeat-y;}
h1 {background: silver;}
h2 {background: url(h2bg.gif) center repeat-x;}
p {background: url(parabg.gif);}
Figure 9-37. Applying many backgrounds to one document
figs/css2_0937.gif

Note the absence of an image on two of the paragraphs. This is because the styles for type1 and type2 paragraphs do not include the URL of a background image. Thus, the value of background-image is reset to its default value none for those two elements.

In older browsers, such as the early versions of Navigator 4, the background property was supported while many of the individual properties, such as background-color, were not.


One final reminder: background is a shorthand property, and, as such, its default values can obliterate previously assigned values for a given element. For example:

h1, h2 {background: gray url(thetrees.jpg) center repeat-x;}
h2 {background: silver;}

Given these rules, h1 elements will be styled according to the first rule. h2 elements will be styled according to the second, which means they'll just have a flat silver background. No image will be applied to h2 backgrounds, let alone centered and repeated horizontally. It is more likely that the author meant to do this:

h1, h2 {background: gray url(trees.jpg) center repeat-x;}
h2 {background-color: silver;}

This lets the background color be changed without wiping out all the other values.

    Previous Section  < Day Day Up >  Next Section