How to apply an opacity without affecting a child element with html/css?

I want to achieve this using html and css:

schema

I have tried to set the opacity of the container to 0.3 and the box to 1, but it doesn't work: both divs have 0.3 opacity.

jsFiddle of my try here

The effect I am trying to achive is a popup box that comes on top of the page. It is highlighted by fading the content below (by lowering the opacity).


You can use opacity in combination with background color, like this:

#container {
    border: solid gold 1px;   
    width: 400px;
    height: 200px;
    background:rgba(56,255,255,0.1);
}

#box {
    border: solid silver 1px;
    margin: 10px;
    width: 300px;
    height: 100px;
    background:rgba(205,206,255,0.1);
}
<div id="container">
    containter text
    <div id="box">
        box text
    </div>
</div>

​Live demo


As far as I know you can't do it in a simple way. There a couple of options here:

  1. Use absolute positioning to position box "inside" the container.

    #container {
        opacity: 0.3;
        background-color: #777788;
        position: absolute;
        top: 100px;
        left: 100px;
        height: 150px;
        width: 300px;
    }
    #box {
        opacity: 1;
        background-color: #ffffff;
        position: absolute;
        top: 110px;
        left: 110px;
        height: 130px;
        width: 270px;
    }
    <div id="container"></div>
    <div id="box">
        <p>Something in here</p>
    </div>
  2. Use Javascript - almost the same as above, but position and size don't have to be hardcoded.


Try using rgba as a 'pre content' overlay to your image, its a good way to keep things responsive and for none of the other elements to be effected.

header #inner_header_post_thumb {
  background-position: center;
  background-size: cover;
  position: relative;
  background-image: url(https://images.pexels.com/photos/730480/pexels-photo-730480.jpeg?w=1260&h=750&auto=compress&cs=tinysrgb);
  border-bottom: 4px solid #222;
}

header #inner_header_post_thumb .dark_overlay {
  position: relative;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.75);
}

header #inner_header_post_thumb .dark_overlay .container .header-txt {
  padding-top: 220px;
  padding-bottom: 220px;
  color: #ffffff;
  text-align:center;
}

header #inner_header_post_thumb .dark_overlay .container .header-txt h1 {
  font-size: 40px;
  color: #ffffff;
}

header #inner_header_post_thumb .dark_overlay .container .header-txt h3 {
  font-size: 24px;
  color: #ffffff;
  font-weight: 300;
}

header #inner_header_post_thumb .dark_overlay .container .header-txt p {
  font-size: 18px;
  font-weight: 300;
}

header #inner_header_post_thumb .dark_overlay .container .header-txt p strong {
  font-weight: 700;
}
<header>
  <div id="inner_header_post_thumb">
    <div class="dark_overlay">
      <div class="container">
        <div class="row header-txt">
          <div class="col-xs-12 col-sm-12">
            <h1>Title On Dark A Underlay</h1>
            <h3>Have a dark background image overlay without affecting other elements</h3>
            <p>No longer any need to re-save backgrounds as .png ... <strong>Awesome</strong></p>

          </div>
        </div>
      </div>
    </div>
  </div>
</header>

See a working codepen here


Using background-color: rgba(#777788, 0.3); instead of opacity could maybe fix the problem.


You can't apply an opacity property without affecting a child element!

"Opacity applies to the element as a whole, including its contents, even though the value is not inherited by child elements. Thus, the element and its children all have the same opacity relative to the element's background, even if they have different opacities relative to one another... If you do not want to apply opacity to child elements, use the background property instead." https://developer.mozilla.org/en-US/docs/Web/CSS/opacity

If you want the opacity to be applied only to the background, without affecting the child elements, use:

background-color: rgba(255, 255, 255, .3)

However, you can achieve the desired effect if you place them inside a div parent element and use CSS position property:

.parent {
  border: solid green 3px;
  position: relative;
  width: 400px;
  height: 200px;
}

.sibling-one {
  border: solid red 3px;
  position: absolute;
  box-sizing: border-box;
  width: 400px;
  height: 200px;
  opacity: .3;
 }

.sibling-two {
    border: solid blue 1px;
    margin: 10px;
    width: 200px;
    height: 100px;
    position: absolute;
    transform: translateY(50%);
}  
<div class="parent">
  <div class="sibling-one">
  <p>A sibling's one element</p>
</div>
<div class="sibling-two">
    <p>A sibling's two element</p>
</div>
</div>