If you have worked much with CSS opacity, you know that one of the most frustrating things about it is that by setting it on any page element, it forces it child elements to be transparent also. I would love to hear a technical explanation for that blunder! There are some workarounds, but they involve fancy positioning footwork and are not ideal for large-scale use.
One of the most common and simple uses for transparency is transparent fills on divs. This is a highly desirable and nice looking effect. For example, if you use textured backgrounds like I like to, you can set off text boxes with this effect:
In a perfect world, all we should have to do to achieve this is to set a background-color and opacity value for the container div. But if we do that, the text will take on that transparency as well and become much less readable.
The solution is to using alpha-transparent PNG’s to fill the backgrounds of our divs. Here are a bunch of the standard “fills” that I use:
![]() Black 90% |
![]() Black 75% |
![]() Black 50% |
![]() Black 25% |
![]() Black 10% |
![]() Brown 90% |
![]() Brown 75% |
![]() Brown 50% |
![]() Brown 25% |
![]() Brown 10% |
![]() Blue 90% |
![]() Blue 75% |
![]() Blue 50% |
![]() Blue 25% |
![]() Blue 10% |
![]() Red 90% |
![]() Red 75% |
![]() Red 50% |
![]() Red 25% |
![]() Red 10% |
![]() Orange 90% |
![]() Orange 75% |
![]() Orange 50% |
![]() Orange 25% |
![]() Orange 10% |
What about IE 6?
Everybody knows IE 6 doesn’t support alpha transparency right? Right. There are fixes for this. My favorite way is the HTC file method. It’s not valid CSS, but you could always toss it in an IE-Only stylesheet. In the demo linked to above, I have applied the hack, but it’s borked on purpose so you can see how IE 6 handles this. It cannot repeat or position the background image if you use this hack. Not a big deal, just make the fill graphic the exact size you need it. Since it’s a flat color, the file size won’t be that much bigger. As a quick note, this method has been known to mess with anchor links on occasion, so I’m wary using it on huge-scale sites without a ton of testing.
I don’t remember the HTC fix offhand (as I generally use Dean Edwards IE7.js for my IE6 fixing and manually fixing any transparent PNG’s I’ve used as background-images), but if it’s just a different way of using the DXImage filter, the link problem in IE6 can generally be fixed by explicitly setting them to position: relative.
That’s an awesome trick.. Well done.
I don’t really undestand why people find this so hard to understand: CSS lives of inheritance, XML and all it’s descendants are build on this more or less hierarchical system — so why should opacity not not be inherited by the child elements? It would make our life much harder, if properties would not be inherited. Just imagine if you’d have to set the text color or size for every single element on your page…
Having said that—thanks a bunch for the great effort you’re putting into your site!
—trice
Not every attribute has to be passed down to it’s children. Think if ‘width’ was inherited… it would just be dumb. This is in the same category. It doesn’t make sense for opacity to cascade. Chances are, you don’t want it to.
Thanks for your reply! If you want to be exact, width is actually kind of inherited. One relatively positioned blocklevel element, placed inside another will “inherit” the parents width, meaning that it will not be wider, right? And if you look at blocklevel elements as boxes, this approach seems just logical (that might just be me) and I would not expect it to react anyhow different.
CSS is btw. not the only technique that works this way—movieclips in Flash work very similar for certain properties. This seems to be just the way of the “least resistance”.
I actually totally agree with you about certain practical issues in the use of opacity—it does make things more complicated sometimes. But imagine if you’re using e.g. jQuery’s fadeOut(), which makes use of the opacity property to fade out an element of your page, you for obvious reasons don’t want to apply the method to all of the element’s children. Because that’s what you’d have to do if opacity would work as you’d like it.
Greetings,
—trice
Yeah, width was a pretty bad example there =), as clearly block children of blocks do inherit width. Border might be a better example, where you wouldn’t want all children to have a border just because a parent does.
I think you make an excellent point in favor of opacity cascading though, setting the opacity to zero on a parent does make the most sense if all the children become invisible as well. I think jQuery would be smart enough to make it happen regardless of the CSS spec, but it does make things easier.
I think the “blunder” though, is that you can’t fight your way out of it. If you set your parent to 0.4 opacity, and the children inherit it, that’s fine, as long as you can bump the children back up if you want.
That’s very true. I’d like more access in these cases as well.— Maybe CSS4 then. When was that to be ready? 3034 or something? :D
Have nice day,
—trice
One method that I have used in several recent sites is super sleight. Just pop in the link to the supersleight javascript file, and design your site as normal and all your pngs will have the transparency. Any positioning works. No more stretching out images or having to hack and reposition things for IE.
The only thing is there CAN be a little flash of the “grey” in the areas with the transparencies in IE6 when it first loads. It’s quick, barely noticeable.
“My favorite way is the HTC file method” my favorite too. Its working good. But I havent these images. Thank you for your shared.
Just beware that IE6 will freak out if you replace too many PNG’s with the filter:alpha (which is what all the methods do).
There are a number of scripts if you use any javascript libraries (I used mootools and jquery – and they both will do inline styles and stylesheet conversions).
I just look forward to when it can be dropped as a supported browser, which, in my line of work will probably be never.
If you using plain image with alpha-color (not a pattern, of smth like this), you can use 1px image even for IE:
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='grey.png', sizingMethod='scale');
Scale means “scale grey.png to fit block bounds”.
Very good to know pepelsbey. I suppose using the HTC method you’d have to go in and alter that file. Not sure, haven’t really dug around in there much to see if there is a built in way to handle having some images scale and others not.