20 August, 2007

This post is in: Accessibility, CSS, Voluntary Sector, Web design

Using CSS to add opaque text to transparent backgrounds

CSS doesn’t currently allow for an element to have a transparent background with opaque text: the text will also be transparent. On top of that, any child elements will inherit the transparency. But there are ways…

I’ve just redesigned this blog (come on, it could be worse), and I wanted the title to sit in a box on top of the image, and for the image to show through the background of the box; thus:

Image showing transparent background to opaque text.

I did this using css positioning:

  1. I put the image in a div, and absolutely positioned the div at the top of the page;
  2. I then created two identical versions of the title box, and absolutely positioned one over the top of the other:
  3. the top one (title) has the text, with no opacity set;
  4. the bottom one (titleBox) has a background colour with the opacity set to a degree of transparency; the text is also in this div, to ensure the box size matches that of the upper div. The text is hidden behind that of the upper div.

However, what if I also wanted to add another div below these? At the moment it would have to be positioned absolutely, meaning that any resizing of the text could upset the flow of the document. My solution was:

  1. Put both divs into one new div (topRight);
  2. Div titleBox comes first (though I guess it doesn’t matter if you add a z-index), with the default relative positioning;
  3. Div title come next, positioned absolutely at the top (ie of div topRight).

Now any new content will flow as expected, relative to the div titleBox.

Here’s the css (trimmed down for the sake of clarity):

  • #topRight {
  • position:absolute;
  • top:30px;
  • right:0;
  • }
  • #title, #titleBox {
  • margin:0;
  • padding:10px;
  • }
  • #titleBox {
  • opacity:0.2;
  • color:#fff;
  • }
  • #title {
  • background:none;
  • z-index:1;
  • position:absolute;
  • top:0;
  • }

Opacity appears to be supported by most browsers now (with the usual notable exception of Internet Explorer), though I haven’t tested extensively. I have also since added rounded corners, but these are only visible in Firefox and Safari (using proprietary tags, while the rest of the browsers catch up).

Update (March 2009)

There is now growing support for RGBa, which enables the addition of alpha transparency to a colour. Whereas opacity applies to all contents of an element, RGBa can apply just to the background and not the text.

So far browsers support the following, which would give a paragraph a red background:

  • p {
  • background-color: rgb(255, 0, 0);
  • }

With opacity the paragraph’s background would be transparent but so would the text it contains:

  • p {
  • background-color: rgb(255, 0, 0);
  • opacity: 0.5;
  • }

(Note: Internet Explorer would require filter: alpha(opacity=50).)

With rgba we can give the paragraph a 50% transparent background, leaving the text unaltered and allowing anything behind to show through:

  • p {
  • background-color: rgba(255, 0, 0, 0.5);
  • }

You can also see where I’ve begun playing with rgba.

Accessibility,CSS,Voluntary Sector,Web design

5 Responses to “Using CSS to add opaque text to transparent backgrounds”

  1. GrahamNo Gravatar says:

    Michael,
    I think all you need to do to get opacity working for IE is add “filter: alpha(opacity = 20);” to your #titleBox declaration, so it would look like this:

    #titleBox {
    opacity:0.2;
    filter: alpha(opacity = 20);
    color:#fff;
    }
    Give it a whirl …
    -graham

  2. MichaelNo Gravatar says:

    Thanks Graham, I’ll give that a go.

  3. lindsayNo Gravatar says:

    Hey.. I hate to tell you this, but looking at your source code was easier for me to understand what you were trying to say than reading your tutorial. I think it would be easiest to understand if you actually put the HTML code and the CSS and explain it that way…

    I must have tried 5 times to do what you said in your tutorial, then i saw where you used the transparent BG with the opaque text, looked at your source and then copied that and worked with it that way.

    just a little suggestion.. Its a GREAT technique, and the ONLY one that I have seen that has worked thus far.. So  THANKS for posting.. Just maybe add a little more info to creating the HTML

  4. MichaelNo Gravatar says:

    Thanks Lindsay. This wasn’t actually written as a tutorial but as a way of recording what I’d done (this is my personal blog, not an educational tool), and published in case others found it useful (which you did).

    The reason the html isn’t shown is because (without a plugin at least) WordPress tries to render it, which causes no end of trouble.

    When I updated the post the other day I did think I should make it clearer, so if I get a chance I’ll see if I can find a good way of displaying html in WordPress posts. :-)

  5. LeeNo Gravatar says:

    Hey all,

    to get the filter working in all versions of IE, just add a zoom:1 entry to the css class. Happy days.

Leave a Reply

Creative Commons License