Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 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!

like image 597
mikepr Avatar asked May 26 '11 21:05

mikepr


People also ask

How do you apply opacity without affecting a child element?

Answer: Use the CSS RGBA colors There is no CSS property like "background-opacity" that you can use only for changing the opacity or transparency of an element's background without affecting its child elements.

How do I change the opacity of text without affecting it?

The percentage of opacity is calculated as Opacity% = Opacity * 100 To set the opacity only to the background and not the text inside it. It can be set by using the RGBA color values instead of the opacity property because using the opacity property can make the text inside it fully transparent element.

Which of the opacity property makes the element completely transparent?

The opacity property sets the opacity level for an element. The opacity-level describes the transparency-level, where 1 is not transparent at all, 0.5 is 50% see-through, and 0 is completely transparent.

In which range the opacity should be given?

The opacity property controls transparency and opacity of an element. Its values range from 0 to 1. Assuming defaults at parent level, an element with an opacity of 1 is completely opaque, whereas and element with an opacity of 0 is completely transparent.


2 Answers

div.parentElem *{filter:inherit;}

see:

http://seanmonstar.com/post/709013028/ie-opacity-ignores-positioned-children

like image 78
gibbitz Avatar answered Oct 17 '22 04:10

gibbitz


Specify width in addition to height for div.childElem. In your case:

width:280px;

Probably has to do with good ol' hasLayout.

like image 1
squidbe Avatar answered Oct 17 '22 04:10

squidbe