Is there any way to have opacity apply to absolutely positioned child elements in ie8
In most browsers, when an html element is only partially opaque, its children "inherit" this opacity. (It isn't quite inheritance--more correctly, the entire image is assembled, including the parent and its children recursively, and then the opacity is applied to the entire thing.)
In IE8 (and I would assume also for earlier versions of IE), this is not always what happens with opacity. If the child elements have position:static (the default if no position is specified), then it does work as I described above. However, it appears to be the case that, if the position is set to anything else (e.g., absolute, or relative), then the child element is fully opaque.
I want to know how to make the opacity correctly affect both the parent and the child elements but still keep the child element with position:absolute;
Here is an example of the problem. The following code is supposed to make a translucent gray box with a translucent blue surrounding area, on top of a vertical red bar. On Firefox, Chrome, etc., This is what is actually seen. On IE8, the blue box is correctly translucent, but the gray part is opaque.
<!doctype html>
<html>
<head>
<style>
div.parentElem
{
background-color:#0000ff;
position: absolute;
left:75px;
top:75px;
width:300px;
height:225px;
opacity:0.5;
filter:alpha(opacity=50);
}
div.childElem
{
background-color:#808080;
position: absolute;
left: 10px;
right: 10px;
top: 10px;
bottom: 10px;
}
div.redBar
{
position: absolute;
left:150px;
top:50px;
height:350px;
width:25px;
background-color: #ff0000;
}
</style>
</head>
<body>
<div class="redBar"></div>
<div class="parentElem">
<div class="childElem"></div>
</div>
</body>
</html>
Obviously, this is just a toy example--I could have had a single div with a blue border and a gray background to achieve the desired effect. In the real scenario, I am layering several different divs, each of which has a png background image to dynamically build an image.
My first attempted workaround was to apply opacity to both the parent and the child, either by setting the filter on the child to alpha(opacity=50); or simply setting filter:inherit;. This does not achieve the desired result because it makes a translucent blue rectangle with a translucent gray rectangle on top of it. The empty space in the middle ends up being translucent blue-ish gray whereas it should be translucent gray. Similarly, it does not work to make the elements siblings. Any solution needs to compose the two images before applying any transparency to anything.
In my research, I found some suggestions that applying either zoom:1; or float:none; to the inner element might resolve the issue, but neither worked for me.
My eventual workaround was to give the child element position:static. It's kind of an ugly solution, but what I would do to apply it to the above example is change the style of the child element to look like:
div.childElem
{
background-color:#808080;
position:static;
margin-left:10px;
margin-right:10px;
height:205px;
margin-top:10px;
}
It's kind of an ugly solution because it means that I have to know the height of the object. Also, in the real case where I am composing several different开发者_如何学JAVA png's, and I would like them to be logical siblings, I have to put them all in a nested parent-child-grandchild-etc. relationship. It also prevents me from adding any textual elements except on the very top of the stack (the innermost div) without messing up the positioning. It does work, though, and it looks the same in all browsers.
Is there any way to avoid such a horrid workaround and have opacity correctly affect the child elements without making the position static? Thanks!
div.parentElem *{filter:inherit;}
see:
http://seanmonstar.com/post/709013028/ie-opacity-ignores-positioned-children
Specify width in addition to height for div.childElem. In your case:
width:280px;
Probably has to do with good ol' hasLayout.
As only IE understands filter
rule you can use it on children elements when you know they're positionned...
I didn't find "proper" solution =/
I was able to find one way to have opacity correctly apply to absolutely positioned children. When I give the page no doctype whatsoever, the opacity is correctly applied. Realistically, because this forces the browser into quirks mode, it is usually not a viable solution.
A minor correction to your question. This odd behavior happens only in IE8. Both IE7 and IE9 display the expected behavior (where child elements are overlaid onto the parent element first, and the whole composite group then has the filter applied). IE8 is also broken when the parent element is position:relative (and when the children are either absolute or relative).
Short answer: set an alpha filter of the desired opacity on the child element.
Here is an a detailed explanation with examples: http://jacklmoore.com/notes/ie-opacity-inheritance/
I've had some success with
selector {
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
filter: alpha(opacity=50);
z-index: -1;
}
I'm using -1, as it doesn't seem to mess with the z-ordering as much as a positive z-index, but from what I've found, any non-auto/inherit/0 z-index works.
精彩评论