How To Work With Transparent Colors And Images In CSS

Being able to control the transparency of design elements is something we’ve been able to do with css for a few years. However, I often see questions from people, particularly in regards to the opacity property and how child elements inherit opacity from parent elements, which typically isn’t desired.

Having seen one of these questions recently, I thought I’d walk through how to work with transparency and the different ways to create transparent elements in web pages. Let’s start the conversation with opacity.

Transparent bowls and vase

CSS Opacity

Opacity in css is very easy to use. It’s single property that takes a number between 0 and 1 as its lone value. A value of 0 means selected elements will be completely transparent and a value of 1 means they’ll be entirely opaque.

1
.element {opacity: 0.5; }

The above should work in all current browsers and it’s been that way for awhile. IE8 and below are where it won’t work, however you can use IE’s filter property to achieve the same results.

1
.element { filter: alpha(opacity=50);  }

Still pretty simple. The downside to opacity is that when you set opacity on an element it’s children will inherit that same opacity.

Think about a div with a few paragraphs inside. Maybe you want the background of the div to be semi-transparent to allow what’s behind it to show through. Odds are you’d still like the text inside to be fully opaque so it’s easily read. However, because the paragraphs are children of the div, they too will be semi-transparent.

Workarounds to this problem have often involved some kind of css positioning. For example instead of having the paragraphs inside the div, one or the other would be positioned to make it appear like the paragraphs were inside instead of being inside. IE actually has a simpler solution. Setting position: relative on the child element, prevents the opacity of the parent from being inherited.

However there are better solutions than positioning. Which you use will depend on what it is you want to be transparent.

Color Transparency

If what you want to be transparent is a color or color gradient then instead of the opacity property you can use the alpha color properties rgba or hsla. In each the ‘a’ stands for alpha and it works just like opacity above. Where rgb will be values between 0 and 255 to represent red, green, and blue, the ‘a’ will take a number between 0 and 1 that defines how transparent or opaque the color should show.

1
.element { background: rgba(255, 0, 255, 0.5 }

Alternatively you can use hsla (hue, saturation, lightness, alpha) instead and it’ll work the same way. At the moment there’s no alpha channel on colors specified in hexadecimal notation.

Unlike the standalone opacity, the alpha color channel isn’t inherited. In the case of the paragraphs inside a div you’d set the background color of the div in either rgba or hsla and the text in the paragraphs would display fully opaque.

Browser support is the same as with opacity, or everything but IE8 and below and once again the filter property can be used to make this work on IE7 and IE8.

1
2
.element { filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#90ff00ff, endColorstr=#88ff00ff);  } /* IE7 */
.element { -ms-filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#90ff00ff, endColorstr=#88ff00ff);  } /* IE8 */

A little more complicated than rgba, but not all that difficult to work with.

The above lines of code should produce the same result as the rgba from earlier. Here the alpha value is placed first and since we have to use hex notation I used 88, which is midway between 00 and ff. The only difference in the 2 lines above is you need to use the -ms vendor prefix for IE8.

Transparent Images

What happens if you want to have an image be transparent? In that case you can use png alpha transparency, which means adding the alpha transparency to the image itself in your image editor of choice. IE6 and below don’t support png alpha, but you probably don’t support IE6 much, if at all, at this point.

IE7 and IE8 support png alpha, but have a weird issue where if you then set an opacity on the image, you won’t get what you expect. You can read about the bug in more detail through the links below.

There’s another way to get transparent images and it’s using opacity again. Children will still inherit from the parent, but Nicolas Gallagher found a nice way around that. His solution is to place the image and opacity on either the :before or :after pseudo elements.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.element {
   position:relative;
   z-index:1;
}

.element:before {
   content:"";
   position:absolute;
   z-index:-0;
   top:0;
   bottom:0;
   left:0;
   right:0;
   background:url("path-to-image.jpg");
   opacity:0.5;
}

Above the :before pseudo element has been positioned to sit behind the parent element and to stretch from edge to edge. You set an image on the background of the pseudo element and then set its opacity of 0.5 to make it semi-transparent. The great thing is child elements of .element won’t inherit this opacity since it’s not applied directly to the element, but to its pseudo element.

Closing Thoughts

As I mentioned at the start, none of this is all that new, but I know people still have issues working with transparency. A few years ago the inheritance issue was a legitimate concern, but today there are workarounds depending on the specifics of what you’re trying to do.

If it’s a solid color you want to be transparent then use rgba or hsla. If it’s an image then either use png alpha transparency or go with the pseudo element fix. If you need to support older versions of IE, be prepared to use one of the filter properties, which are easy to use.

While you can easily get transparency to work, I’d suggest being careful using it. That’s less for technical reasons and more for design reasons. This is just opinion, but I don’t care for transparency all that much. Even if you can get the text inside a transparent container to render fully opaque, it’s still going to be harder to read since you’re letting other things show through. Odds are that will only decrease the contrast between text and background.

That doesn’t mean you shouldn’t use it, but think about why you’re making something transparent and ask yourself if it really improves your design. More often when I’ve seen it used it doesn’t, though I have seen it used well and know that plenty of people do like how it looks.

Download a free sample from my book, Design Fundamentals.

7 comments

    • Thanks Nauman.

      I liked his trick as soon as I saw it. I haven’t had a chance to play around with it and test it a lot, but I figured it would work well.

      Seems so obvious in hindsight.

    • They are well known, but I still see enough questions about transparency that I figured it was worth a post covering everything. I think some equate transparency completely with the opacity property and forget the rest.

      The pseudo element trick is nice.

Leave a Reply

Your email address will not be published.

css.php