How to give text or an image a transparent background using CSS?

Either use a semi-transparent PNG image or use CSS 3:

background-color: rgba(255, 0, 0, 0.5);

Here's an article from css3.info, _Opacity, RGBA and compromise_ (2007-06-03).


<p style="background-color: rgba(255, 0, 0, 0.5);">
  <span>Hello, World!</span>
</p>

.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;
}

<p class="pane">
    <span class="back" style="background-color: green; opacity: 0.6;"></span>
    <span class="cont" style="color: white;">Hello world</span>
</p>

The position: relative on pane is important; it tells back layer to fit to the pane's size. (If you need the <p> tag to be absolute, 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-old 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 background inset adjustment (via top/bottom/left/right) and/or background pinning (via removing one of the left/right or top/bottom pairs) is to use the following CSS instead:

.pane > .back {
    position: absolute;
    width: auto; height: auto;
    top: 0px; bottom: 0px; left: 0px; right: 0px;
}

As written, this works in Firefox, Safari, Chrome, IE8+, and Opera, although IE7 and IE6 require extra CSS and expressions, IIRC, and last time I checked, the second CSS variation does not work in Opera.

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.

A fuller demo, showing off the flexiblity of this technique by using it in tandem with display: inline-block, and with both auto & specific widths/min-heights:

.pane, .pane > .back, .pane > .cont { display: block; }
.pane {
    position: relative;
    width: 175px; min-height: 100px;
    margin: 8px;
}

.pane > .back {
    position: absolute; z-index: 1;
    width: auto; height: auto;
    top: 8px; bottom: 8px; left: 8px; right: 8px;
}

.pane > .cont {
    position: relative; z-index: 10;
}

.debug_red { background: rgba(255, 0, 0, 0.5); border: 1px solid rgba(255, 0, 0, 0.75); }
.debug_green { background: rgba(0, 255, 0, 0.5); border: 1px solid rgba(0, 255, 0, 0.75); }
.debug_blue { background: rgba(0, 0, 255, 0.5); border: 1px solid rgba(0, 0, 255, 0.75); }
<p class="pane debug_blue" style="float: left;">
    <span class="back debug_green"></span>
    <span class="cont debug_red">
        Pane content.<br/>
        Pane content.
    </span>
</p>
<p class="pane debug_blue" style="float: left;">
    <span class="back debug_green"></span>
    <span class="cont debug_red">
        Pane content.<br/>
        Pane content.<br/>
        Pane content.<br/>
        Pane content.<br/>
        Pane content.<br/>
        Pane content.<br/>
        Pane content.<br/>
        Pane content.<br/>
        Pane content.
    </span>
</p>
<p class="pane debug_blue" style="float: left; display: inline-block; width: auto;">
    <span class="back debug_green"></span>
    <span class="cont debug_red">
        Pane content.<br/>
        Pane content.
    </span>
</p>
<p class="pane debug_blue" style="float: left; display: inline-block; width: auto; min-height: auto;">
    <span class="back debug_green"></span>
    <span class="cont debug_red">
        Pane content.<br/>
        Pane content.
    </span>
</p>

And here's a live demo of the technique being used extensively: