You likely use css backgrounds in every site you build. You give an element a background color and tell another element to let a background image repeat. How much do you know about all the other background properties?
Did you know you can control where in the background an image is painted or that you can even specify which part of an element is the background?
I’d like to run through the different background properties css3 offers us. Some of what follows I’m sure will be familiar to you. Some will probably be new. Hopefully this post will give you a greater understanding of a property you use all the time.
Note: As mentioned in the comments below support for some of what’s in this post is less than I originally thought.
The space and round values don’t appear to be working (outside of Opera) for the background-repeat property and issues have been reported with background-position. My apologies for not being aware of these limitations earlier.
CSS Background
The first thing to understand is what does css consider as background and we’ll turn to the css box model with its content, padding, border, and margin for an answer.
Everything except margins is considered background, though we’ll see in a bit that css3 allows us to alter this background painting area to some degree,
Backgrounds can be transparent (the default), filled with color, or filled with images. Different properties determine which is used and in the case of images further properties are used to determine how the images are sized, positioned, and more.
In practice you’ll often use the background shorthand to set all these properties, but let’s look at them individually. I’ll come back to the shorthand later in this post.
background-color
I’m sure you’ve set a css background color before. For those who’ve never used it here’s one way you’d set a background color on paragraphs.
{code type=css}
p {background-color: red;}
{/code}
You can also use hexadecimal or rgb notation instead.
{code type=css}
p {background-color: #f00;}
p {background-color: #ff0000;}
p {background-color: rgb(255, 0, 0;)}
{/code}
All 3 lines of css above are equivalent and set a red background on the paragraph.
One last way to specify a background-color is rgba. The “a” stands for alpha transparency and is set as a fraction between 0 and 1, with 0 being fully transparent and 1 being fully opaque.
{code type=css}
p {background-color: rgba(255, 0, 0, 0.5);}
{/code}
The above sets the background to the same red as before, though at 50% opacity. Browser support for rgba isn’t as good as rgb, but the fallback is generally to present the color as completely opaque or with an “a” of 1.0.
The one thing you might not be familiar with is that the background-color will be clipped according to the background-clip property.
We’ll get to this property shortly, but for now know it’s a way to prevent color from appearing behind the border of your element or even behind the element’s padding.
background-image
I’m sure you’ve also set a background-image before. What’s nice is that in css3 we can add multiple images like so:
{code type=css}
body {background-image: url(“image1”), url(“image2”), url(“image3”)}
{/code}
The above adds 3 background images to the body of a document.
Each image creates a new background layer so the images sit one on top of another. A value of none, an image with 0 width and height, or an image that fails to download still creates a new layer, though one that doesn’t show an image.
The first image in the list is seen as being closest to the viewer and each successive image is one layer further into the background. If a background color is also specified, it’s painted below all images and is furthest from the viewer.
There are two important guidelines you should follow when setting background-images.
- Specify a background-color along with background-image(s) to preserve contrast for text if the images(s) don’t display.
- Don’t use background-images to convey important information as they may not display in all browsers.
Background images will be sized, positioned, and tiled according properties we’ll cover momentarily.
With multiple images the values of these other properties will also be a comma separated list and the first value will correspond to the first image, etc.
If there are excess values at the end of these other properties, they’ll be ignored and if there are not enough the given values are repeated until there are enough to match the images.
Browser support for multiple background images is good in all browsers, except for Internet Explorer 8 and below.
background-repeat
Background-repeat determines how background-images are tiled and has the allowed values of no-repeat, repeat-x, repeat-y, repeat, space, and round.
- no-repeat — the image isn’t tiled
- repeat-x — the image tiles horizontally only
- repeat-y — the image tiles vertically only
- repeat — the image tiles both horizontally and vertically
- space — the image will tile to fill the background with as many complete images as possible. The images wil then be spaced evenly with first and last images touching the edge
- round — image will be tiled to fill the background with as many complete images as possible. The images will then be scaled to fit the area exactly.
You’ve no doubt used all of the first 4 values above, but how many of you were aware of the last 2. I know I wasn’t.
{code type=css}
body {
background-repeat: no-repeat, repeat-y, space;
}
{/code}
Assuming the 3 background images from above the first wouldn’t be repeated, the second would be repeated vertically, and the last would use the space algorithm to repeat the images both horizontally and vertically.
background-attachment
The background-attachment property determines how the image scrolls with respect to the viewport. It has the 3 values below
- fixed — the image doesn’t scroll. It’s fixed where it is.
- local — the image scrolls with the element’s content. It’s fixed to the content.
- scroll — the image scrolls with element. It’s fixed to element.
{code type=css}
body {
background-attachment: fixed;
}
{/code}
The above keeps the background-image fixed in place with respect to the body.
I can’t think of a single time I’ve ever set the background-attachment to local. Most of the time I leave it as the default (scroll), but sometimes fixing the image can make for an interesting effect.
background-position
By default background images are painted at the top-left corner of an element, but they don’t have to be. You can change where they’re positioned through the background-position property.
The background-position can be set horizontally, vertically, or both. Horizontally you can use the values center, left, and right. Vertically you can use the values center, top, and bottom. In both directions you can set a % or length.
{code type=css}
body {
background-position: right 20px;
}
{/code}
The above positions the image 20px down along the right edge of the element.
When 2 values are set the first is assumed to be the horizontal and the second vertical, unless the keywords say otherwise. When only one is set the second is assumed to be center.
% and length represent an offset from the top-left corner, however if 3 or 4 values are given then % or length is offset from keyword
{code type=css}
body {
background-position: bottom 10px right 20%;
}
{/code}
The above paints the image 10px from bottom and 20% from right.
CSS3 Background Properties
Outside of the ability to use multiple background images all of the above have been available for awhile. Below are some new background properties specific to css3.
They work in most browsers, however they won’t work in IE8 or below.
background-clip
Earlier in this post I mentioned that the background was everything in the element’s box except for the margins. This and the next property can alter that.
The background-clip property determines where a background is clipped, which determines the background painting area. It has the following values
- border-box — painted within (clipped to) border
- padding-box — painted within (clipped to) padding
- content-box — painted within (clipped to) content
{code type=css}
body {
background-clip: content-box;
}
{/code}
The above clips the image or color so it only displays behind the content part of the element’s box. The color or image will not show behind the element’s padding or border.
This is another property I can’t claim to have used, but having learned of it I can think of times when I would want to.
background-origin
Similar is the background-origin property, which sets the origin for the background-position property. It’s values are the same as background-clip.
- border-box — positioned relative to border box
- padding-box — positioned relative to padding box
- content-box — positioned relative to content box
{code type=css}
body {
background-origin: padding-box;
}
{/code}
Above the image or color would start inside the body border and behind any padding on the body.
Note that if the background-attachment is fixed then background-position has no effect.
background-size
The last property we can set on backgrounds is background-size. While images will be whatever size they are by default (the auto value) you can control the image size in several ways.
The obvious values are the usual % and length.
{code type=css}
body {
background-size: 300px 40%;
}
{/code}
The first value is the width and the second the height. Negative values are not permitted.
If only one value is given, the second is assumed to be auto. When one value or both are set to auto the image size is resolved using the images aspect ratio or failing that 100%.
There are 2 other values that control how the image might be sized.
- contain — scales the image while preserving its aspect ratio to the largest size that both height and width can still fit within the background area
- cover — scales the image while preserving its aspect ratio to the smallest size that both height and width can still fit within the background area
If neither width or height is specified then the image is sized based on the contain method above.
Background Property Shorthand
While you might set the above background properties individually, most of the time you’ll likely use the shorthand. In the past I’ve always placed the color first, the image second, and then any other properties after without thinking much to their order.
It’s always seemed to work, but it’s incorrect. The W3C specifies the following order.
- <bg-layer> = <bg-image> || <bg-position> [ / <bg-size> ]? || <repeat-style> || <attachment> || <box>{1,2}
- <final-bg-layer> = <bg-image> || <bg-position> [ / <bg-size> ]? || <repeat-style> || <attachment> || <box>{1,2} || <background-color>
{code type=css}
background-image background-position / background-size background-repeat background-attachment background-origin background-clip color;
{/code}
Color can only be used on the final background layer. A single background image is of course the final background layer.
{code type=css}
body {background: url(“image.png”) top left / 95% 95% no-repeat scroll padding-box content-box #333;}
{/code}
The above is equivalent to:
{code type=css}
body {
background-image: url(“image.png”);
background-position: top left;
background-size: 95% 95%;
background-repeat: no-repeat;
background-attachment: scroll;
background-origin: padding-box;
background-clip: content-box;
background-color: #333};
}
{/code}
You don’t have to specify a value for every property in the shorthand. To use the shorthand on multiple images you would separate each set of values by a comma, remembering only to use a color on the last set of values.
Summary
CSS backgrounds are something you no doubt use on every site. However you may not have been familiar with each of the different background properties available or some of the values for the properties you do know.
While much of the time you’ll happily let defaults reign with most of these properties, a few give you some nice control over how and where your background images display.
Browsers support is generally good for multiple images and the three new properties, origin, clip, and size, but do know that IE8 and below won’t support them.
That may or may not be an issue depending on which browsers you need to support and how you’re using these properties.
Hopefully this post has given you a greater understanding of a property you likely know well. Have you used any of the new properties or worked with multiple background images yet? If so how have you used them and how have they worked for you?
Download a free sample from my book, Design Fundamentals.
body {
background-position: bottom 10px right 20%;
}
Really? Define the origin and an additional offset? That would be to cool. Just tried it in several current browsers, but it doesn’t seem to work.
It should be working. Are you using it to position a background image within an element?
If you want to send me the image and code and I’ll see if I notice why it’s not working for you.
Interresting article.
Just want to add a cool other properties : background cover 🙂
html {
background: url(images/bg.jpg) no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
It will stretch, keeping the aspect ratio, and not showing border/margin (Full screen bg)
Cool. That’s not a property I saw while researching this article. Where did you find it?
= [ | | auto ]{1,2} | cover | contain
see http://www.w3.org/TR/css3-background/#background-size
D’oh. How did I miss that? Oh wait I did mention that value with background-size. I guess I was confused yesterday thinking that cover was a new property. That’s what I get for replying too early in the morning and before I’ve had sufficient coffee. 🙂
Steven, as always, this is a lovely article. Thanks for sharing.
Regarding what @Ape wrote before, I’d like to add that defining multiple values for background-position is something real and it works.
But this is CSS3 stuff and apparently there is support only in Opera 11 and IE9 / IE10.
Hope this helps.
Thanks Caitlin. My bad for not testing this. I saw that multiple images worked and guess I didn’t check enough that some of the associated properties would work with it.
Thanks.
Just created a test on cssdesk.com:
http://cssdesk.com/AFdH6
But as Catalin already said below, there seems to be no support in browsers like FF7, Safari 5.1, Chrome 14 at this point of time.
Thanks Ape. Again my bad on this. Strange that for a change something is working in the latest IE, but not FF, Safari, and Chrome. You don’t get to say that all too often. 🙂
As I had never known of this either and couldn’t reproduce it I googled for this and found out it’s a CSS3 improvement (http://www.w3.org/TR/css3-background/#the-background-position) that hasn’t been implemented yet by none of the major browsers apparently.
What browser did you use to test this?
I didn’t test it. Usually I do, but I was a bit rushed getting this post out and trusted what I thought was true. Clearly that wasn’t a good idea.
http://jsfiddle.net/7mCbx/
Seems only to work in IE9 for me.
Hi Steven
It might be a good idea to edit the article to reflect the correct browser support for these properties. I just spent half an hour trying to implement space/round in a dev site, before coming back to the article only to strew through the comments and find out that most of these only work in the latest Opera. I imagine i’m not the only one
Sorry about that. I did link out to sites that give more detailed browser support through the post. Would it help if I added a section to the post with a list of those links?
Surfed in on Smashing Mag tweet, I too was very interested in the offset background position, but it doesn’t work in any of the browsers I tried.
A caveat might be handy here.
Good article anyway 🙂
Thanks Ben. I added a general note to the top of the post to alert people not all the properties and values mentioned here work in all browsers. Hopefully that’s enough to keep people from wasting time wondering why they might not be working.
U r amazing!!!!!!!!!!!!!!
Been searchin for over an hour now, and finally i got the required info here.
I was tryin to put three background images under one tag, out of them one was repeated, others were hearder n footer. Footer was gettin eaten by repeatin image.
And where i checked they all talked abt usin different div tags for each.
Finally ur tutorial came to my rescue(first image comes on top, next underneath it, n so on…n there was my mistake, repeatin image was right in the middle)
Thanx a LOT!!!!!!!!!!!!!
U R AWESOME!
Glad I could help Neo. I know how it is to be frustrated by tutorials that don’t work. On the bright side I bet you never forget how background-images work now. 🙂
Hi Steven! You’re super clear and the post is awesome; I’ll check right now your book but I wanted to ask you: is there any way to control the space between every image in a repeated pattern? Like controlling the space or round space?
Thanks, man!