For a simple semi-transparent background color, the above solutions (CSS3 or bg images) are the best options. However, if you don't want to rely on CSS3 or want to do something fancier (e.g. animation, multiple backgrounds, etc.), you can try the “pane technique”:
<style type="text/css" media="all">
.pane, .pane > .back, .pane > .cont { display: block; }
.pane {
position: relative;
}
.pane > .back {
position: absolute;
width: 100%; height: 100%;
top: auto; bottom: auto; left: auto; right: auto;
}
.pane > .cont {
position: relative;
z-index: 10;
}
</style>
<p class="pane">
<span class="back" style="background: green; opacity: 0.6; filter: alpha(opacity=60);"></span>
<span class="cont">Hello World</span>
</p>
Basically, the technique works by using two “layers” inside of the outer pane element, one (the “back”) that fits the size of the pane element without affecting the flow of content, and one (the “cont”) that contains the content and helps determine the size of the pane.
The “position: relative” on pane is important; it tells back layer to fit to the pane's size. (If you really need the <p> tag to be absolute, you'll have to change the pane from a <p> to a <span> and wrap all that in a absolutely-position <p> tag.)
The main advantage this technique has over similar ones listed above is that the pane doesn't have to be a specified size; as coded above, it will fit full-width (normal block-element layout) and only as high as the content. The outer pane element can be sized any way you please, as long as it's rectangular (i.e. inline-block will work; plain-ol' inline will not).
Also, it gives you a lot of freedom for the background; you're free to put really anything in the back element and have it not affect the flow of content (if you want multiple full-size sub-layers, just make sure they also have position: absolute, width/height: 100%, and top/bottom/left/right: auto).
One variation to allow more flexible background layer/sub-layer placement is to use this CSS instead:
.pane > .back {
position: absolute;
width: auto; height: auto;
top: 0px; bottom: 0px; left: 0px; right: 0px;
}
If you play around with the top/bottom/left/right values, you can inset the background by however much you want. Also, if you set a width and just left or right (not both), you can pin background layers to a specific side (same goes for height and just top or bottom).
The technique, as written, works in Firefox, Safari, Chrome, IE7+, and Opera. If you need it to work in IE6, you'll have to play around with expressions to get the width/height: 100% to work right. I believe the second CSS variation does not work in Opera.
If you want to see the whole technique in a real-world application, check out http://christmas-card-2009.slippyd.com/?f=s&n=RXhhbXBsZSBmb3IgdGhlIFN0YWNrIE92ZXJmbG93IENvbW11bml0eQ%3D%3D%0A&sn=T3ZlcmZsb3dpYW5z%0A
The animated, corner-faded background, the envelope, and the letter paper all use this technique with multiple image layers. While there are likely simpler ways to do this (e.g. using a CSS3 radial gradient instead of four ginormous corner-fade sub-layers or CSS3 background image positioning), the approach does work for anything you need in a background in every popular browser.
Things to watch out for:
- Floating elements inside of the cont layer will not be contained. You'll need to make sure they are cleared or otherwise contained, or they'll slip out of the bottom.
- Margins go on the pane element and padding goes on the cont element. Don't do use the opposite (margins on the cont or padding on the pane) or you'll discover oddities such as the page always being slightly wider than the browser window.
- As mentioned, the whole thing needs to be block or inline-block. Feel free to use <div>s instead of <span>s to simplify your CSS.
Hope this helps.