By Louis Lazaris on July 28th, 2009
Categories: CSS, Web Design Tutorials, XHTML | 13 Comments
This is a quick tip to demonstrate a way to work around the problem of child elements in your HTML inheriting the “alpha” settings of their parent. This tip is not necessarily recommended, because it creates extra markup and is a little bit messy. But I’m sure it could come in handy in a rare case, depending on the layout of the elements involved, the content, the type of site, etc.
First, here is the CSS code necessary to make an HTML element semi-transparent:
#alpha {
background: url(bicycle.jpg) no-repeat 0 0;
filter: alpha(opacity=30);
-moz-opacity: 0.3;
-khtml-opacity: 0.3;
opacity: 0.3;
}
The different settings are for the various browsers. You can easily find out which ones are for which browsers through a quick Google search, so I won’t go into that here. The last 4 lines ensure that the background image of the bicycle is shown “washed out” or with 30% opacity (or 70% transparency, if you’re a pessimist!).
The problem occurs when we add child elements to the html element that this code affects. All child elements will inherit the same opacity settings, even if you try to specify full opacity for all those elements (which would be too troublesome to do anyhow).
How can we work around this problem? In some instances, you could visually mimic a parent-child relationship between the elements using absolute positioning, and this will resolve the problem.
View Demo Comparing Two Examples
You’ll notice at the demo link above that the same set of visual elements is duplicated. The one on the left has the typical parent-child inheritance issue, so the blue background is shown washed out, at 30% opacity. But the example on the right looks exactly the way we want it to look — the opacity is set only on the element that has the bicycle background image.
You could add more elements to the section on the right, and none of them will inherit the transparency, because, technically, they are not children of the bicycle <div>. They are actually siblings of the bicycle <div>, but they are positioned absolutely so that visually they appear to be children.
Here is the section of code that styles the second example:
#alpha_wrapper {
width: 540px;
height: 360px;
float: left;
position: relative;
color: #fff;
}
#alpha_2 {
background: transparent url(bicycle.jpg) no-repeat 0 0;
width: 540px;
height: 440px;
float: left;
filter: alpha(opacity=30);
-moz-opacity: 0.3;
-khtml-opacity: 0.3;
opacity: 0.3;
}
#text_holder_2 {
background: blue;
position: absolute;
top: 20px;
left: 20px;
width: 500px;
}
The key is the fact that the bicycle element does not actually have any children, so it doesn’t affect anything else on the page. But, as with virtually any hack or workaround, there are drawbacks.
This method does qualify as a workaround that could be considered if you ever want to remove inherited opacity settings on child elements. But its drawbacks are probably convincing enough to prevent its use in most cases, so it’s important to mention them here.
NEW COMMENT RULES: I no longer have any tolerance for people that use blog comments for link bait and branding. Although comments are pre-approved, comment rules are as follows:
If any of the above rules are broken, one of the following will happen:
I apologize for the inconvenience, but I'm no longer interested in comments that detract from the discussion. Thank you for your cooperation.
I agree this problem is a thing that definetly needs a workaround. But as you write, this should not be a recommended way to solve the problem. I would ideally recommend using jQuery/javascript soulutions instead of this fix, but at least you demonstrate it´s possible to make such a hack – which is great. The attributes -moz-opacity and -khtml-opacity should by the way not be necessary to make a element transparent and cross-browser compatible (see http://www.quirksmode.org/css/opacity.html). :-)
Another option, although not always ideal, is to use flash for the item that requires transparency adjustment and publish with a transparent background. As long as you publish in player 7, 99% of people can see it.
Nicely explained. I was hoping to see a 3rd option though! How about png opacity?
p.s. your captcha refresh doesn’t work!
I think it’s tempting to use CSS for everything, but the fact is that in this current day – CSS just doesn’t do everything. Trying to make it do so causes more code and a loss of the page flow
The BEST method for this is to use a small transparent PNG (make sure you install a PNG-hack script for those on IE6) and go that route. It will run fast and work like it’s supposed to.
That is how I usually do. But, unfortunately, not always possible to use this method.
@Phil:
The captcha refresh seems to work fine for me. Can you describe exactly what went wrong and/or test it again? Thanks.
When I saw this link on Twitter, I thought WOW – A SOLUTION!
But so disappointed this was what I did many months back. :( Well, still hopes for more improvements on CSS opacity support.
@ Bård Øien
I don’t think JavaScript is a good solution either, what happens if somebody disabled JavaScript? Then the user would get the same problem. I prefer the one used here, however I wouldn’t call it a hack. It’s normal CSS syntax and it isn’t using tricks
This must be the most misleading post ever. The title asks a question your post does not answer, by moving the alphatised content behind the text it is no longer a child element.
This is a relevant method to use alpha for backgrounds but it is often not possible as content is dynamic.
I got excited for no reason : (
@Si:
It’s not misleading, because it gives a solution to the problem of children inheriting opacity. Just because the end result causes the elements to no longer, technically, be “children” doesn’t mean it’s not a viable solution to how to treat “child” elements.
People use Javascript to manipulate the DOM all the time, but that doesn’t mean those solutions are invalid.
I suppose I could have put the word “child” in quotes to be more technical about it. :o)
You’re example doesn’t work in ie6 (parallels)… the blue box and the text have disappeared on the right hand example.
Which browsers were you testing in? ie6 is still being used by lots of people, if you are producing accessible web sites you still have to consider them.
To any ie6 users who are reading this… it’s time to move on & get a different browser, save us developers a headache!
@Alex:
Thanks for the heads up on that. Generally, for tutorial stuff, I don’t do extensive testing in every browser. I just don’t have the time for that. But I usually do a quick check in the basic 3 (IE6, IE7, FF3).
I’ve corrected it, and at the same time learned an interesting way to fix IE6 absolute positioning bugs: Add “clear: both” to the absolutely positioned element.
Thanks again.
The simplest and most reliable solution, it seems to me, is to employ a background image, such as a 1 x 1 pixel semi-transparent png or gif that repeats through the containing element. This allows for a dynamic (elastic) result based upon the changing dimensions of the content within the container.