How not to apply opacity to a child element?

I have a div with opacity applied, but this div has child element. I don't want opacity to be applied to these child elements, would there be any way to solve this?

Example: http://jsfiddle.net/qSsC3/1 /

Link Code:

.div-pai{
  width: 400px;
  height: 400px;
  background-color: black;
  position: fixed;
  opacity: 0.7;
}
 .div-filho{
  width: 150px;
  height: 150px;
  position:absolute;
  top: 50%;
  left: 50%;
  background: blue;
  margin-top: -75px;
  margin-left: -75px;
  opacity: 1;
}
<div class="div-pai">
    <div class="div-filho"></div>
</div>
Author: hugocsl, 2014-02-03

5 answers

I don't think it's possible, but there are workarounds.

If you need opacity only in the background, you can apply a color rgba:

background-color: rgba(0,0,0,.7);

Fiddle. Note that there is no support for IE

If you need to apply opacity to every element and not just the background, you'll have to break the hierarchy and turn them into siblings.

There is a third way, which works if you are looking for an effect overlay . It would be to create a pseudo-element ::before that covers every element .div-pai and sits below the .div-filho:

.div-pai:before {
    content: '';
    position: absolute;
    top: 0; bottom: 0;
    left: 0; right: 0;
    background: white;
    opacity: 0.3;
}

Fiddle.

In this way :before is a sibling of .div-filho and is below this without the need for z-index due to the order of the elements. Note that .div-pai needs a position different from static, I did not add this to the code because its .div-pai is already fixed.
A .div-filho also needs a position other than static to appear on the :before. Otherwise, positioned elements always appear over static elements (see stacking without z-indexin English ).


As for support for IE8, you can use a .gif/.png with transparency as background, or apply the proprietary filter property of IE5-8. I haven't had success applying the filter to a pseudo-element, but it works if we pollute the markup a bit (adding a div).

To test on IE8: http://jsfiddle.net/qSsC3/12/show /

<div class="div-pai">
    <div class="overlay"></div>
    <div class="div-filho"></div>
</div>

.overlay {
    content: '';
    position: absolute;
    top: 0; bottom: 0;
    left: 0; right: 0;
    background: white;

    filter: alpha(opacity=30); /* IE5-8 */
    opacity: 0.3; /* IE9+ e todos browsers modernos */
}

Or, without creating any other element, another form that works cross-browser (IE8+), using an image as background: http://jsfiddle.net/qSsC3/17/show

.div-pai:before {
    content: '';
    position: absolute;
    top: 0; bottom: 0;
    left: 0; right: 0;

    background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNXG14zYAAAAWdEVYdENyZWF0aW9uIFRpbWUAMDIvMDMvMTSFgaz/AAAADUlEQVQImWP4//+/LwAJSQNLpIypVwAAAABJRU5ErkJggg==);
}

I encoded the image as Data-URI to make it easier to put in the answer, but it won't make a difference to link to a file .png/.gif (except it would generate an extra request). I will also note that IE

 12
Author: Fabrício Matté, 2014-02-03 13:43:59

Is not possible, the opacity of the children will always be relative to that of the parents. If you are needing to change only the background color, it could instead of opacity. modify the background attribute:

.div-pai {width: 400px;height: 400px; position: fixed; background-color: rgba(0, 0, 0, 0.7); }
 3
Author: iuristona, 2014-02-03 12:40:31

In this case, I would advise using an image in .png with opacity as background in the parent element, an image of 1px by 1px repeating, is very light, some older browsers do not support this property.

 3
Author: Jefferson Alison, 2014-02-03 12:40:51

Well, it is not possible to do the way you want, but a suggestion is to remove the div.pai and just use the div.filho and put a border on it, which would result in the same thing, but its child element "central" would not be opacity, see the example I did in jsfiddle

I used the following CSS code:

.div-filho{
    width: 150px;
    height: 150px;
    position:absolute;
    background: blue;
    border: 150px solid rgba(0,0,0,0.75);
}

And remove the div.pai from the HTML.

 0
Author: Paulo Roberto Rosa, 2014-02-03 12:47:27

I've been through similar case, but the opacity in Javascript is always inherited by the elements, there is no way you remove it, so what I usually do is create an element that is exactly the same position and dimension of the element that would be the parent with transparency, but this element is not child, it is after the transparent element and contains what would be its children.

The result can be seen in this jsfiddle.

Will be compatible with all browsers and it can be applied to any element.

Example:

<div class='div_transparente'></div>
<div class='div_opaca_sem_fundo_por_cima_da_div_transparente'>
    <div class='div_filho_opaca_com_preenchimento'></div>
</div>

There are several solutions to get around the problem when it is background, but if your div, is on top of an image, video, or something like that, I personally prefer this solution as it is generic to all cases.

 0
Author: Gabriel Gartz, 2014-02-03 13:18:38