Related
I do not want to inherit the child opacity from the parent in CSS.
I have one div which is the parent, and I have another div inside the first div which is the child.
I want to set the opacity property in the parent div, but I don't want the child div to inherit the opacity property.
How can I do that?
Instead of using opacity, set a background-color with rgba, where 'a' is the level of transparency.
So instead of:
background-color: rgb(0,0,255); opacity: 0.5;
use
background-color: rgba(0,0,255,0.5);
Opacity is not actually inherited in CSS. It's a post-rendering group transform. In other words, if a <div> has opacity set you render the div and all its kids into a temporary buffer, and then composite that whole buffer into the page with the given opacity setting.
What exactly you want to do here depends on the exact rendering you're looking for, which is not clear from the question.
A little trick if your parent is transparent and you would like your child to be the same, but defined exclusively (e.g. to overwrite the user agent styles of a select dropdown):
.parent {
background-color: rgba(0,0,0,0.5);
}
.child {
background-color: rgba(128,128,128,0);
}
As others have mentioned in this and other similar threads, the best way to avoid this problem is to use RGBA/HSLA or else use a transparent PNG.
But, if you want a ridiculous solution, similar to the one linked in another answer in this thread (which is also my website), here's a brand new script I wrote that fixes this problem automatically, called thatsNotYoChild.js:
http://www.impressivewebs.com/fixing-parent-child-opacity/
Basically it uses JavaScript to remove all children from the parent div, then reposition the child elements back to where they should be without actually being children of that element anymore.
To me, this should be a last resort, but I thought it would be fun to write something that did this, if anyone wants to do this.
Opacity of child element is inherited from the parent element.
But we can use the css position property to accomplish our achievement.
The text container div can be put outside of the parent div but with absolute positioning projecting the desired effect.
Ideal Requirement------------------>>>>>>>>>>>>
HTML
<div class="container">
<div class="bar">
<div class="text">The text opacity is inherited from the parent div </div>
</div>
</div>
CSS
.container{
position:relative;
}
.bar{
opacity:0.2;
background-color:#000;
z-index:3;
position:absolute;
top:0;
left:0;
}
.text{
color:#fff;
}
Output:--
the Text is not visible because inheriting opacity from parent div.
Solution ------------------->>>>>>
HTML
<div class="container">
<div class="text">Opacity is not inherited from parent div "bar"</div>
<div class="bar"></div>
</div>
CSS
.container{
position:relative;
}
.bar{
opacity:0.2;
background-color:#000;
z-index:3;
position:absolute;
top:0;
left:0;
}
.text{
color:#fff;
z-index:3;
position:absolute;
top:0;
left:0;
}
Output :
the Text is visible with same color as of background because the div is not in the transparent div
The question didn't defined if the background is a color or an image but since #Blowski have already answered for coloured backgrounds, there's a hack for images below:
background: linear-gradient(rgba(0,0,0,.6), rgba(0,0,0,.6)), url('image.jpg');
This way you can manipulate the color of your opacity and even add nice gradient effects.
.wrapper {
width: 630px;
height: 420px;
display: table;
background: linear-gradient(
rgba(0,0,0,.8),
rgba(0,0,0,.8)),
url('http://cdn.moviestillsdb.com/sm/35bc3c6a2b791425de6caf8b9391026e/rambo-iii.jpg');
}
h1 {
display: table-cell;
vertical-align: middle;
text-align: center;
color: #fff;
}
<div class="wrapper">
<h1>Question 5770341</h1>
</div>
There is no one size fits-all approach, but one thing that I found particularly helpful is setting opacity for a div's direct children, except for the one that you want to keep fully visible. In code:
<div class="parent">
<div class="child1"></div>
<div class="child2"></div>
<div class="child3"></div>
<div class="child4"></div>
</div>
and css:
div.parent > div:not(.child1){
opacity: 0.5;
}
In case you have background colors/images on the parent you fix color opacity with rgba and background-image by applying alpha filters
Answers above seems to complicated for me, so I wrote this:
#kb-mask-overlay {
background-color: rgba(0,0,0,0.8);
width: 100%;
height: 100%;
z-index: 10000;
top: 0;
left: 0;
position: fixed;
content: "";
}
#kb-mask-overlay > .pop-up {
width: 800px;
height: 150px;
background-color: dimgray;
margin-top: 30px;
margin-left: 30px;
}
span {
color: white;
}
<div id="kb-mask-overlay">
<div class="pop-up">
<span>Content of no opacity children</span>
</div>
</div>
<div>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin vitae arcu nec velit pharetra consequat a quis sem. Vestibulum rutrum, ligula nec aliquam suscipit, sem justo accumsan mauris, id iaculis mauris arcu a eros. Donec sem urna, posuere id felis eget, pharetra rhoncus felis. Mauris tellus metus, rhoncus et laoreet sed, dictum nec orci. Mauris sagittis et nisl vitae aliquet. Sed vestibulum at orci ut tempor. Ut tristique vel erat sed efficitur. Vivamus vestibulum velit condimentum tristique lacinia. Sed dignissim iaculis mattis. Sed eu ligula felis. Mauris diam augue, rhoncus sed interdum nec, euismod eget urna.
Morbi sem arcu, sollicitudin ut euismod ac, iaculis id dolor. Praesent ultricies eu massa eget varius. Nunc sit amet egestas arcu. Quisque at turpis lobortis nibh semper imperdiet vitae a neque. Proin maximus laoreet luctus. Nulla vel nulla ut elit blandit consequat. Nullam tempus purus vitae luctus fringilla. Nullam sodales vel justo vitae eleifend. Suspendisse et tortor nulla. Ut pharetra, sapien non porttitor pharetra, libero augue dictum purus, dignissim vehicula ligula nulla sed purus. Cras nec dapibus dolor. Donec nulla arcu, pretium ac ipsum vel, accumsan egestas urna. Vestibulum at bibendum tortor, a consequat eros. Nunc interdum at erat nec ultrices. Sed a augue sit amet lacus sodales eleifend ut id metus. Quisque vel luctus arcu.
</p>
</div>
kb-mask-overlay it's your (opacity) parent, pop-up it's your (no opacity) children. Everything below it's rest of your site.
It seems that display: block elements do not inherit opacity from display: inline parents.
Codepen example
Maybe because it's invalid markup and the browser is secretly separating them? Because source doesn't show that happening. Am I missing something?
Below worked for me:
Changed
From:
opacity: 0.52;
background-color: #7c7c7c;
To:
opacity: 1 !important;
background-color: rgba(124, 124, 124, 0.52) !important;
To convert the hex & opacity to rgba,
use a website like http://hex2rgba.devoth.com/
<!--Background opacity-->
<style>
.container1 {
width: 200px;
height: 200px;
background: rgba(0, 0, 0, .5);
margin-bottom: 50px;
}
</style>
<div class="container1">
<div class="box1">Text</div>
</div>
<!--Before, after, z-index opacity-->
<style>
.container2 {
width: 200px;
height: 200px;
position: relative;
margin-bottom: 100px;
}
.container2:after {
content: '';
display: block;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
background: black;
opacity: .5;
z-index: 1;
}
.box2 {
position: relative;
z-index: 2;
}
</style>
<div class="container2">
<div class="box2">Text</div>
</div>
<!--Outline opacity-->
<style>
.container3 {
width: 200px;
height: 200px;
outline: 50px solid rgba(0, 0, 0, .5);
margin: 50px;
}
.box3 {
position: relative;
left: -16px;
}
</style>
<div class="container3">
<div class="box3">Text</div>
</div>
I also faced the same issues, after doing some googling I found some solutions ( 3-ways ) of this problem.
I am sharing the solutions here, you can try any of these.
Option-1:
Use a pseudo markup element before or after as the background
.parentContainer {
position: relative;
}
.parentContainer:before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #fff;
opacity: 0.6;
}
.childContent {
position: relative;
color: red;
z-index: 1;
}
Option-2:
Use rgba colors with alpha value instead of opacity.
<div id="parentContainer" style="background: rgba(255,255,255,0.6);">
<div id="childContent">
Content ...
</div>
</div>
Option-3:
Use background div with absolute position one element over another.
<div class="parentContainer">
<div class="childContent">
Here is the content.
</div>
<div class="background"></div>
</div>
.parentContainer {
position: relative;
}
.childContent {
position: relative;
color: White;
z-index: 5;
}
.background {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
background-color: Black;
z-index: 1;
opacity: .5;
}
If you have to use an image as the transparent background, you might be able to work around it using a pseudo element:
html
<div class="wrap">
<p>I have 100% opacity</p>
</div>
css
.wrap, .wrap > * {
position: relative;
}
.wrap:before {
content: " ";
opacity: 0.2;
background: url("http://placehold.it/100x100/FF0000") repeat;
position: absolute;
width: 100%;
height: 100%;
}
My answer is not about static parent-child layout, its about animations.
I was doing an svg demo today, and i needed svg to be inside div (because svg is created with parent's div width and height, to animate the path around), and this parent div needed to be invisible during svg path animation (and then this div was supposed to animate opacity from 0 to 1, it's the most important part). And because parent div with opacity: 0 was hiding my svg, i came across this hack with visibility option (child with visibility: visible can be seen inside parent with visibility: hidden):
.main.invisible .test {
visibility: hidden;
}
.main.opacity-zero .test {
opacity: 0;
transition: opacity 0s !important;
}
.test { // parent div
transition: opacity 1s;
}
.test-svg { // child svg
visibility: visible;
}
And then, in js, you removing .invisible class with timeout function, adding .opacity-zero class, trigger layout with something like whatever.style.top; and removing .opacity-zero class.
var $main = $(".main");
setTimeout(function() {
$main.addClass('opacity-zero').removeClass("invisible");
$(".test-svg").hide();
$main.css("top");
$main.removeClass("opacity-zero");
}, 3000);
Better to check this demo http://codepen.io/suez/pen/54bbb2f09e8d7680da1af2faa29a0aef?editors=011
I solved this problem by first creating and saving a faded image which I then used in the css background. I used the following python code:
from PLI import Image
bg = Image.open('im1.jpg')
fg = Image.open('im2.jpg')
#blend at ratio .3
Image.blend(bg,fg,.3).save('out.jpg')
Here, im1.jpg was simply a white image of the same dimensions as im2.jpg.
On mac you can use Preview editor to apply opacity to a white rectangle laid over your .png image before you put it in your .css.1) ImageLogo2) Create a rectangle around the imageRectanle around logo3) Change background color to whiterectangle turned white4) Adjust rectangle opacityopaque image
For other people trying to make a table (or something) look focused on one row using opacity. Like #Blowski said use color not opacity. Check out this fiddle: http://jsfiddle.net/2en6o43d/
.table:hover > .row:not(:hover)
Assign opacity 1.0 to the child recursively with:
div > div { opacity: 1.0 }
Example:
div.x { opacity: 0.5 }
div.x > div.x { opacity: 1.0 }
<div style="background-color: #f00; padding:20px;">
<div style="background-color: #0f0; padding:20px;">
<div style="background-color: #00f; padding:20px;">
<div style="background-color: #000; padding:20px; color:#fff">
Example Text - No opacity definition
</div>
</div>
</div>
</div>
<div style="opacity:0.5; background-color: #f00; padding:20px;">
<div style="opacity:0.5; background-color: #0f0; padding:20px;">
<div style="opacity:0.5; background-color: #00f; padding:20px;">
<div style="opacity:0.5; background-color: #000; padding:20px; color:#fff">
Example Text - 50% opacity inherited
</div>
</div>
</div>
</div>
<div class="x" style="background-color: #f00; padding:20px;">
<div class="x" style="background-color: #0f0; padding:20px;">
<div class="x" style="background-color: #00f; padding:20px;">
<div class="x" style="background-color: #000; padding:20px; color:#fff">
Example Text - 50% opacity not inherited
</div>
</div>
</div>
</div>
<div style="opacity: 0.5; background-color: #000; padding:20px; color:#fff">
Example Text - 50% opacity
</div>
I do not want to inherit the child opacity from the parent in CSS.
I have one div which is the parent, and I have another div inside the first div which is the child.
I want to set the opacity property in the parent div, but I don't want the child div to inherit the opacity property.
How can I do that?
Instead of using opacity, set a background-color with rgba, where 'a' is the level of transparency.
So instead of:
background-color: rgb(0,0,255); opacity: 0.5;
use
background-color: rgba(0,0,255,0.5);
Opacity is not actually inherited in CSS. It's a post-rendering group transform. In other words, if a <div> has opacity set you render the div and all its kids into a temporary buffer, and then composite that whole buffer into the page with the given opacity setting.
What exactly you want to do here depends on the exact rendering you're looking for, which is not clear from the question.
A little trick if your parent is transparent and you would like your child to be the same, but defined exclusively (e.g. to overwrite the user agent styles of a select dropdown):
.parent {
background-color: rgba(0,0,0,0.5);
}
.child {
background-color: rgba(128,128,128,0);
}
As others have mentioned in this and other similar threads, the best way to avoid this problem is to use RGBA/HSLA or else use a transparent PNG.
But, if you want a ridiculous solution, similar to the one linked in another answer in this thread (which is also my website), here's a brand new script I wrote that fixes this problem automatically, called thatsNotYoChild.js:
http://www.impressivewebs.com/fixing-parent-child-opacity/
Basically it uses JavaScript to remove all children from the parent div, then reposition the child elements back to where they should be without actually being children of that element anymore.
To me, this should be a last resort, but I thought it would be fun to write something that did this, if anyone wants to do this.
Opacity of child element is inherited from the parent element.
But we can use the css position property to accomplish our achievement.
The text container div can be put outside of the parent div but with absolute positioning projecting the desired effect.
Ideal Requirement------------------>>>>>>>>>>>>
HTML
<div class="container">
<div class="bar">
<div class="text">The text opacity is inherited from the parent div </div>
</div>
</div>
CSS
.container{
position:relative;
}
.bar{
opacity:0.2;
background-color:#000;
z-index:3;
position:absolute;
top:0;
left:0;
}
.text{
color:#fff;
}
Output:--
the Text is not visible because inheriting opacity from parent div.
Solution ------------------->>>>>>
HTML
<div class="container">
<div class="text">Opacity is not inherited from parent div "bar"</div>
<div class="bar"></div>
</div>
CSS
.container{
position:relative;
}
.bar{
opacity:0.2;
background-color:#000;
z-index:3;
position:absolute;
top:0;
left:0;
}
.text{
color:#fff;
z-index:3;
position:absolute;
top:0;
left:0;
}
Output :
the Text is visible with same color as of background because the div is not in the transparent div
The question didn't defined if the background is a color or an image but since #Blowski have already answered for coloured backgrounds, there's a hack for images below:
background: linear-gradient(rgba(0,0,0,.6), rgba(0,0,0,.6)), url('image.jpg');
This way you can manipulate the color of your opacity and even add nice gradient effects.
.wrapper {
width: 630px;
height: 420px;
display: table;
background: linear-gradient(
rgba(0,0,0,.8),
rgba(0,0,0,.8)),
url('http://cdn.moviestillsdb.com/sm/35bc3c6a2b791425de6caf8b9391026e/rambo-iii.jpg');
}
h1 {
display: table-cell;
vertical-align: middle;
text-align: center;
color: #fff;
}
<div class="wrapper">
<h1>Question 5770341</h1>
</div>
There is no one size fits-all approach, but one thing that I found particularly helpful is setting opacity for a div's direct children, except for the one that you want to keep fully visible. In code:
<div class="parent">
<div class="child1"></div>
<div class="child2"></div>
<div class="child3"></div>
<div class="child4"></div>
</div>
and css:
div.parent > div:not(.child1){
opacity: 0.5;
}
In case you have background colors/images on the parent you fix color opacity with rgba and background-image by applying alpha filters
Answers above seems to complicated for me, so I wrote this:
#kb-mask-overlay {
background-color: rgba(0,0,0,0.8);
width: 100%;
height: 100%;
z-index: 10000;
top: 0;
left: 0;
position: fixed;
content: "";
}
#kb-mask-overlay > .pop-up {
width: 800px;
height: 150px;
background-color: dimgray;
margin-top: 30px;
margin-left: 30px;
}
span {
color: white;
}
<div id="kb-mask-overlay">
<div class="pop-up">
<span>Content of no opacity children</span>
</div>
</div>
<div>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin vitae arcu nec velit pharetra consequat a quis sem. Vestibulum rutrum, ligula nec aliquam suscipit, sem justo accumsan mauris, id iaculis mauris arcu a eros. Donec sem urna, posuere id felis eget, pharetra rhoncus felis. Mauris tellus metus, rhoncus et laoreet sed, dictum nec orci. Mauris sagittis et nisl vitae aliquet. Sed vestibulum at orci ut tempor. Ut tristique vel erat sed efficitur. Vivamus vestibulum velit condimentum tristique lacinia. Sed dignissim iaculis mattis. Sed eu ligula felis. Mauris diam augue, rhoncus sed interdum nec, euismod eget urna.
Morbi sem arcu, sollicitudin ut euismod ac, iaculis id dolor. Praesent ultricies eu massa eget varius. Nunc sit amet egestas arcu. Quisque at turpis lobortis nibh semper imperdiet vitae a neque. Proin maximus laoreet luctus. Nulla vel nulla ut elit blandit consequat. Nullam tempus purus vitae luctus fringilla. Nullam sodales vel justo vitae eleifend. Suspendisse et tortor nulla. Ut pharetra, sapien non porttitor pharetra, libero augue dictum purus, dignissim vehicula ligula nulla sed purus. Cras nec dapibus dolor. Donec nulla arcu, pretium ac ipsum vel, accumsan egestas urna. Vestibulum at bibendum tortor, a consequat eros. Nunc interdum at erat nec ultrices. Sed a augue sit amet lacus sodales eleifend ut id metus. Quisque vel luctus arcu.
</p>
</div>
kb-mask-overlay it's your (opacity) parent, pop-up it's your (no opacity) children. Everything below it's rest of your site.
It seems that display: block elements do not inherit opacity from display: inline parents.
Codepen example
Maybe because it's invalid markup and the browser is secretly separating them? Because source doesn't show that happening. Am I missing something?
Below worked for me:
Changed
From:
opacity: 0.52;
background-color: #7c7c7c;
To:
opacity: 1 !important;
background-color: rgba(124, 124, 124, 0.52) !important;
To convert the hex & opacity to rgba,
use a website like http://hex2rgba.devoth.com/
<!--Background opacity-->
<style>
.container1 {
width: 200px;
height: 200px;
background: rgba(0, 0, 0, .5);
margin-bottom: 50px;
}
</style>
<div class="container1">
<div class="box1">Text</div>
</div>
<!--Before, after, z-index opacity-->
<style>
.container2 {
width: 200px;
height: 200px;
position: relative;
margin-bottom: 100px;
}
.container2:after {
content: '';
display: block;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
background: black;
opacity: .5;
z-index: 1;
}
.box2 {
position: relative;
z-index: 2;
}
</style>
<div class="container2">
<div class="box2">Text</div>
</div>
<!--Outline opacity-->
<style>
.container3 {
width: 200px;
height: 200px;
outline: 50px solid rgba(0, 0, 0, .5);
margin: 50px;
}
.box3 {
position: relative;
left: -16px;
}
</style>
<div class="container3">
<div class="box3">Text</div>
</div>
I also faced the same issues, after doing some googling I found some solutions ( 3-ways ) of this problem.
I am sharing the solutions here, you can try any of these.
Option-1:
Use a pseudo markup element before or after as the background
.parentContainer {
position: relative;
}
.parentContainer:before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #fff;
opacity: 0.6;
}
.childContent {
position: relative;
color: red;
z-index: 1;
}
Option-2:
Use rgba colors with alpha value instead of opacity.
<div id="parentContainer" style="background: rgba(255,255,255,0.6);">
<div id="childContent">
Content ...
</div>
</div>
Option-3:
Use background div with absolute position one element over another.
<div class="parentContainer">
<div class="childContent">
Here is the content.
</div>
<div class="background"></div>
</div>
.parentContainer {
position: relative;
}
.childContent {
position: relative;
color: White;
z-index: 5;
}
.background {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
background-color: Black;
z-index: 1;
opacity: .5;
}
If you have to use an image as the transparent background, you might be able to work around it using a pseudo element:
html
<div class="wrap">
<p>I have 100% opacity</p>
</div>
css
.wrap, .wrap > * {
position: relative;
}
.wrap:before {
content: " ";
opacity: 0.2;
background: url("http://placehold.it/100x100/FF0000") repeat;
position: absolute;
width: 100%;
height: 100%;
}
My answer is not about static parent-child layout, its about animations.
I was doing an svg demo today, and i needed svg to be inside div (because svg is created with parent's div width and height, to animate the path around), and this parent div needed to be invisible during svg path animation (and then this div was supposed to animate opacity from 0 to 1, it's the most important part). And because parent div with opacity: 0 was hiding my svg, i came across this hack with visibility option (child with visibility: visible can be seen inside parent with visibility: hidden):
.main.invisible .test {
visibility: hidden;
}
.main.opacity-zero .test {
opacity: 0;
transition: opacity 0s !important;
}
.test { // parent div
transition: opacity 1s;
}
.test-svg { // child svg
visibility: visible;
}
And then, in js, you removing .invisible class with timeout function, adding .opacity-zero class, trigger layout with something like whatever.style.top; and removing .opacity-zero class.
var $main = $(".main");
setTimeout(function() {
$main.addClass('opacity-zero').removeClass("invisible");
$(".test-svg").hide();
$main.css("top");
$main.removeClass("opacity-zero");
}, 3000);
Better to check this demo http://codepen.io/suez/pen/54bbb2f09e8d7680da1af2faa29a0aef?editors=011
I solved this problem by first creating and saving a faded image which I then used in the css background. I used the following python code:
from PLI import Image
bg = Image.open('im1.jpg')
fg = Image.open('im2.jpg')
#blend at ratio .3
Image.blend(bg,fg,.3).save('out.jpg')
Here, im1.jpg was simply a white image of the same dimensions as im2.jpg.
On mac you can use Preview editor to apply opacity to a white rectangle laid over your .png image before you put it in your .css.1) ImageLogo2) Create a rectangle around the imageRectanle around logo3) Change background color to whiterectangle turned white4) Adjust rectangle opacityopaque image
For other people trying to make a table (or something) look focused on one row using opacity. Like #Blowski said use color not opacity. Check out this fiddle: http://jsfiddle.net/2en6o43d/
.table:hover > .row:not(:hover)
Assign opacity 1.0 to the child recursively with:
div > div { opacity: 1.0 }
Example:
div.x { opacity: 0.5 }
div.x > div.x { opacity: 1.0 }
<div style="background-color: #f00; padding:20px;">
<div style="background-color: #0f0; padding:20px;">
<div style="background-color: #00f; padding:20px;">
<div style="background-color: #000; padding:20px; color:#fff">
Example Text - No opacity definition
</div>
</div>
</div>
</div>
<div style="opacity:0.5; background-color: #f00; padding:20px;">
<div style="opacity:0.5; background-color: #0f0; padding:20px;">
<div style="opacity:0.5; background-color: #00f; padding:20px;">
<div style="opacity:0.5; background-color: #000; padding:20px; color:#fff">
Example Text - 50% opacity inherited
</div>
</div>
</div>
</div>
<div class="x" style="background-color: #f00; padding:20px;">
<div class="x" style="background-color: #0f0; padding:20px;">
<div class="x" style="background-color: #00f; padding:20px;">
<div class="x" style="background-color: #000; padding:20px; color:#fff">
Example Text - 50% opacity not inherited
</div>
</div>
</div>
</div>
<div style="opacity: 0.5; background-color: #000; padding:20px; color:#fff">
Example Text - 50% opacity
</div>
I do not want to inherit the child opacity from the parent in CSS.
I have one div which is the parent, and I have another div inside the first div which is the child.
I want to set the opacity property in the parent div, but I don't want the child div to inherit the opacity property.
How can I do that?
Instead of using opacity, set a background-color with rgba, where 'a' is the level of transparency.
So instead of:
background-color: rgb(0,0,255); opacity: 0.5;
use
background-color: rgba(0,0,255,0.5);
Opacity is not actually inherited in CSS. It's a post-rendering group transform. In other words, if a <div> has opacity set you render the div and all its kids into a temporary buffer, and then composite that whole buffer into the page with the given opacity setting.
What exactly you want to do here depends on the exact rendering you're looking for, which is not clear from the question.
A little trick if your parent is transparent and you would like your child to be the same, but defined exclusively (e.g. to overwrite the user agent styles of a select dropdown):
.parent {
background-color: rgba(0,0,0,0.5);
}
.child {
background-color: rgba(128,128,128,0);
}
As others have mentioned in this and other similar threads, the best way to avoid this problem is to use RGBA/HSLA or else use a transparent PNG.
But, if you want a ridiculous solution, similar to the one linked in another answer in this thread (which is also my website), here's a brand new script I wrote that fixes this problem automatically, called thatsNotYoChild.js:
http://www.impressivewebs.com/fixing-parent-child-opacity/
Basically it uses JavaScript to remove all children from the parent div, then reposition the child elements back to where they should be without actually being children of that element anymore.
To me, this should be a last resort, but I thought it would be fun to write something that did this, if anyone wants to do this.
Opacity of child element is inherited from the parent element.
But we can use the css position property to accomplish our achievement.
The text container div can be put outside of the parent div but with absolute positioning projecting the desired effect.
Ideal Requirement------------------>>>>>>>>>>>>
HTML
<div class="container">
<div class="bar">
<div class="text">The text opacity is inherited from the parent div </div>
</div>
</div>
CSS
.container{
position:relative;
}
.bar{
opacity:0.2;
background-color:#000;
z-index:3;
position:absolute;
top:0;
left:0;
}
.text{
color:#fff;
}
Output:--
the Text is not visible because inheriting opacity from parent div.
Solution ------------------->>>>>>
HTML
<div class="container">
<div class="text">Opacity is not inherited from parent div "bar"</div>
<div class="bar"></div>
</div>
CSS
.container{
position:relative;
}
.bar{
opacity:0.2;
background-color:#000;
z-index:3;
position:absolute;
top:0;
left:0;
}
.text{
color:#fff;
z-index:3;
position:absolute;
top:0;
left:0;
}
Output :
the Text is visible with same color as of background because the div is not in the transparent div
The question didn't defined if the background is a color or an image but since #Blowski have already answered for coloured backgrounds, there's a hack for images below:
background: linear-gradient(rgba(0,0,0,.6), rgba(0,0,0,.6)), url('image.jpg');
This way you can manipulate the color of your opacity and even add nice gradient effects.
.wrapper {
width: 630px;
height: 420px;
display: table;
background: linear-gradient(
rgba(0,0,0,.8),
rgba(0,0,0,.8)),
url('http://cdn.moviestillsdb.com/sm/35bc3c6a2b791425de6caf8b9391026e/rambo-iii.jpg');
}
h1 {
display: table-cell;
vertical-align: middle;
text-align: center;
color: #fff;
}
<div class="wrapper">
<h1>Question 5770341</h1>
</div>
There is no one size fits-all approach, but one thing that I found particularly helpful is setting opacity for a div's direct children, except for the one that you want to keep fully visible. In code:
<div class="parent">
<div class="child1"></div>
<div class="child2"></div>
<div class="child3"></div>
<div class="child4"></div>
</div>
and css:
div.parent > div:not(.child1){
opacity: 0.5;
}
In case you have background colors/images on the parent you fix color opacity with rgba and background-image by applying alpha filters
Answers above seems to complicated for me, so I wrote this:
#kb-mask-overlay {
background-color: rgba(0,0,0,0.8);
width: 100%;
height: 100%;
z-index: 10000;
top: 0;
left: 0;
position: fixed;
content: "";
}
#kb-mask-overlay > .pop-up {
width: 800px;
height: 150px;
background-color: dimgray;
margin-top: 30px;
margin-left: 30px;
}
span {
color: white;
}
<div id="kb-mask-overlay">
<div class="pop-up">
<span>Content of no opacity children</span>
</div>
</div>
<div>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin vitae arcu nec velit pharetra consequat a quis sem. Vestibulum rutrum, ligula nec aliquam suscipit, sem justo accumsan mauris, id iaculis mauris arcu a eros. Donec sem urna, posuere id felis eget, pharetra rhoncus felis. Mauris tellus metus, rhoncus et laoreet sed, dictum nec orci. Mauris sagittis et nisl vitae aliquet. Sed vestibulum at orci ut tempor. Ut tristique vel erat sed efficitur. Vivamus vestibulum velit condimentum tristique lacinia. Sed dignissim iaculis mattis. Sed eu ligula felis. Mauris diam augue, rhoncus sed interdum nec, euismod eget urna.
Morbi sem arcu, sollicitudin ut euismod ac, iaculis id dolor. Praesent ultricies eu massa eget varius. Nunc sit amet egestas arcu. Quisque at turpis lobortis nibh semper imperdiet vitae a neque. Proin maximus laoreet luctus. Nulla vel nulla ut elit blandit consequat. Nullam tempus purus vitae luctus fringilla. Nullam sodales vel justo vitae eleifend. Suspendisse et tortor nulla. Ut pharetra, sapien non porttitor pharetra, libero augue dictum purus, dignissim vehicula ligula nulla sed purus. Cras nec dapibus dolor. Donec nulla arcu, pretium ac ipsum vel, accumsan egestas urna. Vestibulum at bibendum tortor, a consequat eros. Nunc interdum at erat nec ultrices. Sed a augue sit amet lacus sodales eleifend ut id metus. Quisque vel luctus arcu.
</p>
</div>
kb-mask-overlay it's your (opacity) parent, pop-up it's your (no opacity) children. Everything below it's rest of your site.
It seems that display: block elements do not inherit opacity from display: inline parents.
Codepen example
Maybe because it's invalid markup and the browser is secretly separating them? Because source doesn't show that happening. Am I missing something?
Below worked for me:
Changed
From:
opacity: 0.52;
background-color: #7c7c7c;
To:
opacity: 1 !important;
background-color: rgba(124, 124, 124, 0.52) !important;
To convert the hex & opacity to rgba,
use a website like http://hex2rgba.devoth.com/
<!--Background opacity-->
<style>
.container1 {
width: 200px;
height: 200px;
background: rgba(0, 0, 0, .5);
margin-bottom: 50px;
}
</style>
<div class="container1">
<div class="box1">Text</div>
</div>
<!--Before, after, z-index opacity-->
<style>
.container2 {
width: 200px;
height: 200px;
position: relative;
margin-bottom: 100px;
}
.container2:after {
content: '';
display: block;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
background: black;
opacity: .5;
z-index: 1;
}
.box2 {
position: relative;
z-index: 2;
}
</style>
<div class="container2">
<div class="box2">Text</div>
</div>
<!--Outline opacity-->
<style>
.container3 {
width: 200px;
height: 200px;
outline: 50px solid rgba(0, 0, 0, .5);
margin: 50px;
}
.box3 {
position: relative;
left: -16px;
}
</style>
<div class="container3">
<div class="box3">Text</div>
</div>
I also faced the same issues, after doing some googling I found some solutions ( 3-ways ) of this problem.
I am sharing the solutions here, you can try any of these.
Option-1:
Use a pseudo markup element before or after as the background
.parentContainer {
position: relative;
}
.parentContainer:before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #fff;
opacity: 0.6;
}
.childContent {
position: relative;
color: red;
z-index: 1;
}
Option-2:
Use rgba colors with alpha value instead of opacity.
<div id="parentContainer" style="background: rgba(255,255,255,0.6);">
<div id="childContent">
Content ...
</div>
</div>
Option-3:
Use background div with absolute position one element over another.
<div class="parentContainer">
<div class="childContent">
Here is the content.
</div>
<div class="background"></div>
</div>
.parentContainer {
position: relative;
}
.childContent {
position: relative;
color: White;
z-index: 5;
}
.background {
position: absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
background-color: Black;
z-index: 1;
opacity: .5;
}
If you have to use an image as the transparent background, you might be able to work around it using a pseudo element:
html
<div class="wrap">
<p>I have 100% opacity</p>
</div>
css
.wrap, .wrap > * {
position: relative;
}
.wrap:before {
content: " ";
opacity: 0.2;
background: url("http://placehold.it/100x100/FF0000") repeat;
position: absolute;
width: 100%;
height: 100%;
}
My answer is not about static parent-child layout, its about animations.
I was doing an svg demo today, and i needed svg to be inside div (because svg is created with parent's div width and height, to animate the path around), and this parent div needed to be invisible during svg path animation (and then this div was supposed to animate opacity from 0 to 1, it's the most important part). And because parent div with opacity: 0 was hiding my svg, i came across this hack with visibility option (child with visibility: visible can be seen inside parent with visibility: hidden):
.main.invisible .test {
visibility: hidden;
}
.main.opacity-zero .test {
opacity: 0;
transition: opacity 0s !important;
}
.test { // parent div
transition: opacity 1s;
}
.test-svg { // child svg
visibility: visible;
}
And then, in js, you removing .invisible class with timeout function, adding .opacity-zero class, trigger layout with something like whatever.style.top; and removing .opacity-zero class.
var $main = $(".main");
setTimeout(function() {
$main.addClass('opacity-zero').removeClass("invisible");
$(".test-svg").hide();
$main.css("top");
$main.removeClass("opacity-zero");
}, 3000);
Better to check this demo http://codepen.io/suez/pen/54bbb2f09e8d7680da1af2faa29a0aef?editors=011
I solved this problem by first creating and saving a faded image which I then used in the css background. I used the following python code:
from PLI import Image
bg = Image.open('im1.jpg')
fg = Image.open('im2.jpg')
#blend at ratio .3
Image.blend(bg,fg,.3).save('out.jpg')
Here, im1.jpg was simply a white image of the same dimensions as im2.jpg.
On mac you can use Preview editor to apply opacity to a white rectangle laid over your .png image before you put it in your .css.1) ImageLogo2) Create a rectangle around the imageRectanle around logo3) Change background color to whiterectangle turned white4) Adjust rectangle opacityopaque image
For other people trying to make a table (or something) look focused on one row using opacity. Like #Blowski said use color not opacity. Check out this fiddle: http://jsfiddle.net/2en6o43d/
.table:hover > .row:not(:hover)
Assign opacity 1.0 to the child recursively with:
div > div { opacity: 1.0 }
Example:
div.x { opacity: 0.5 }
div.x > div.x { opacity: 1.0 }
<div style="background-color: #f00; padding:20px;">
<div style="background-color: #0f0; padding:20px;">
<div style="background-color: #00f; padding:20px;">
<div style="background-color: #000; padding:20px; color:#fff">
Example Text - No opacity definition
</div>
</div>
</div>
</div>
<div style="opacity:0.5; background-color: #f00; padding:20px;">
<div style="opacity:0.5; background-color: #0f0; padding:20px;">
<div style="opacity:0.5; background-color: #00f; padding:20px;">
<div style="opacity:0.5; background-color: #000; padding:20px; color:#fff">
Example Text - 50% opacity inherited
</div>
</div>
</div>
</div>
<div class="x" style="background-color: #f00; padding:20px;">
<div class="x" style="background-color: #0f0; padding:20px;">
<div class="x" style="background-color: #00f; padding:20px;">
<div class="x" style="background-color: #000; padding:20px; color:#fff">
Example Text - 50% opacity not inherited
</div>
</div>
</div>
</div>
<div style="opacity: 0.5; background-color: #000; padding:20px; color:#fff">
Example Text - 50% opacity
</div>
Okay this is going to be hard to explain. I have a page with two collapsible menus. One is positioned absolutely to the top left. When I collapse it, the remaining content is all squished to the top left, as expected.
The other menu is positioned absolutely to the bottom right. When it's expanded (default state when loading the page) it sits in the bottom right, 5 pixels away from the bottom and right, as expected. However when I collapse it, all of the sudden the remaining content starts from 5 pixels away from bottom and right, and then flows off the page both to the right and below, expanding the page and causing scrollbars.
The desired behavior is for the remaining content to be squished into the bottom right of the page, without changing the page dimensions.
It's going to be tricky to post my code, as a lot of it is generated dynamically via JavaScript.
Each menu consists of two child divs inside a container div. The container div is positioned absolutely (top left or bottom right, depending on which menu). The first child div is the content of the active menu tab, floated left and with a margin-top just tall enough to put it under the menu tabs. The second child div is the menu tabs. This div is positioned absolutely (so as to let the content div flow behind it). Each tab inside the tab div is floated left, so I can add more dynamically.
One of the tabs is always the "hide/show" tab, and basically just toggles display:hidden on the menu's content div.
So, as I understand it, somehow the floated content div keeps the menu from flowing off the page, and when it's "collapsed" (i.e. hidden), there's nothing to keep the absolutely positioned tab div from flowing off the page.
I guess I will attempt to rip out the offending div and css code into it's own page so I can isolate the behavior, and post some coherent code. In the meantime any suggestions are quite welcome.
Thanks!
== Matt
P.S. Normally I would have just made everything in the menu positioned relatively. The reason I went with an absolutely positioned div on top of a floated content div is so I can control whether or not the bottom of the active tab looks "connected" to the content div. If I had both divs relative and just had the tab div sitting on top of the content div, I have no way of removing the content div's black top border in just the right place to make it look like the active tab is connected to it. If someone can think of a way around this while still keeping both divs relative, I'd be down for that too.
I don't have the rep to post images, so here are some links:
Here's what the menu's look like expanded:
http://theroach.net/igp_menutest/css_menus1.png
Here they are collapsed:
http://theroach.net/igp_menutest/css_menus2.png
Here is what I'm going for:
http://theroach.net/igp_menutest/css_menus3.png
UPDATE: I've stripped out the menu code from my JavaScript as much as possible. Here is a JSFiddle with the working code. For some reason, the onclick events aren't working inside the JSFiddle, but it's the exact same code from my test page, so if you can't get it to work in the JSFiddle, try this link to see the behavior. FYI, the javascript doesn't normally rely on giant if-else statements, I just did that so I wouldn't have to post all of the dynamic menu generation code.
P.P.S. I've basically only been testing this in Chrome v20, although I just tested Firefox v13 and IE9 and got the same behavior. I don't care much about cross browser support. This page is being designed only for people using the latest and greatest browsers.
UPDATE2: Updated links. Added relevant portion of jsfiddle code to satisfy new code-in-question requirement:
JS
function tab(id) {
if(id == 'menuCtrlTab1') {
toggle('menuCtrlTab1');
toggle('menuCtrlTab2');
hide('menuCtrlForm2');
show('menuCtrlForm1');
}
else if(id == 'menuCtrlTab2') {
toggle('menuCtrlTab1');
toggle('menuCtrlTab2');
hide('menuCtrlForm1');
show('menuCtrlForm2');
}
else if(id == 'menuCtrlTabHide') {
hide('menuCtrlTab1');
hide('menuCtrlTab2');
hide('menuCtrlFormDiv');
hide('menuCtrlTabHide');
show('menuCtrlTabShow');
}
else if(id == 'menuCtrlTabShow') {
show('menuCtrlTab1');
show('menuCtrlTab2');
show('menuCtrlFormDiv');
hide('menuCtrlTabShow');
show('menuCtrlTabHide');
}
else if(id == 'menuInfoTab1') {
toggle('menuInfoTab1');
toggle('menuInfoTab2');
hide('menuInfoForm2');
show('menuInfoForm1');
}
else if(id == 'menuInfoTab2') {
toggle('menuInfoTab1');
toggle('menuInfoTab2');
hide('menuInfoForm1');
show('menuInfoForm2');
}
else if(id == 'menuInfoTabHide') {
hide('menuInfoTab1');
hide('menuInfoTab2');
hide('menuInfoFormDiv');
hide('menuInfoTabHide');
show('menuInfoTabShow');
}
else if(id == 'menuInfoTabShow') {
show('menuInfoTab1');
show('menuInfoTab2');
show('menuInfoFormDiv');
hide('menuInfoTabShow');
show('menuInfoTabHide');
}
else {
}
}
function toggle(id) {
if(activated(id)) {
deactivate(id);
}
else {
activate(id);
}
}
function hide(id) {
docAddClass(id, 'hidden');
}
function show(id) {
docRemoveClass(id, 'hidden');
}
function activate(id) {
docRemoveClass(id, 'inActive');
docAddClass(id, 'active');
}
function deactivate(id) {
docRemoveClass(id, 'active');
docAddClass(id, 'inActive');
}
function activated(id) {
var e = docGet(id);
if(e.className.search('active') == -1) {
return false;
}
return true;
}
function docGet(id) {
return document.getElementById(id);
}
function docAddClass(id, classToAdd) {
var e = docGet(id);
if(e.className.length <= 0) {
e.className = classToAdd;
}
else {
if(e.className.search(classToAdd) == -1) {
e.className = e.className + ' ' + classToAdd;
}
}
}
function docRemoveClass(id, classToRem) {
var e = docGet(id);
if(e.className.length > 0) {
if(e.className.search(classToRem) != -1) {
e.className = e.className.replace(classToRem, "");
}
}
}
HTML
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<meta name='Author' content='Matt Seng' />
<meta name="Description" content="IGP" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="./style.css" media="screen" />
</head>
<body>
<div id="menuDiv">
<div id="menuCtrl">
<div id="menuCtrlWrapper" class="menuWrapper">
<div id='menuCtrlFormDiv'>
<div id="menuCtrlForm1" class="menuForm">
Tab 1 contents<br>
Lorem ipsum dolor sit amet, consectetur<br>
adipiscing elit. Duis est orci, malesuada<br>
vitae pulvinar nec, varius id felis. Vivamus<br>
et accumsan dui. Donec a nisl id dui gravida<br>
porttitor. Integer sed turpis arcu. Curabitur<br>
nec dolor urna, ac molestie neque. Nunc ac<br>
augue non mi imperdiet semper.
</div>
<div id="menuCtrlForm2" class="menuForm hidden">
Tab 2 contents<br>
Lorem ipsum dolor sit amet, consectetur<br>
adipiscing elit. Duis est orci, malesuada<br>
vitae pulvinar nec, varius id felis. Vivamus<br>
et accumsan dui. Donec a nisl id dui gravida<br>
porttitor. Integer sed turpis arcu. Curabitur<br>
nec dolor urna, ac molestie neque. Nunc ac<br>
augue non mi imperdiet semper.
</div>
</div>
<div id="menuCtrlTabs" class="menuTabs">
<div id="menuCtrlTabShow" class="clickable tab showHide inActive hidden" onclick="tab(this.id);">
Show
</div>
<div id="menuCtrlTabHide" class="clickable tab showHide inActive" onclick="tab(this.id);">
Hide
</div>
<div id="menuCtrlTab1" class="clickable tab secondary active" onclick="tab(this.id);">
1
</div>
<div id="menuCtrlTab2" class="clickable tab secondary inActive" onclick="tab(this.id);">
2
</div>
</div>
</div>
</div>
<div id="menuInfo">
<div id="menuInfoWrapper" class="menuWrapper">
<div id='menuInfoFormDiv'>
<div id="menuInfoForm1" class="menuForm">
Tab 1 contents<br>
Lorem ipsum dolor sit amet, consectetur<br>
adipiscing elit. Duis est orci, malesuada<br>
vitae pulvinar nec, varius id felis. Vivamus<br>
et accumsan dui. Donec a nisl id dui gravida<br>
porttitor. Integer sed turpis arcu. Curabitur<br>
nec dolor urna, ac molestie neque. Nunc ac<br>
augue non mi imperdiet semper.
</div>
<div id="menuInfoForm2" class="menuForm hidden">
Tab 2 contents<br>
Lorem ipsum dolor sit amet, consectetur<br>
adipiscing elit. Duis est orci, malesuada<br>
vitae pulvinar nec, varius id felis. Vivamus<br>
et accumsan dui. Donec a nisl id dui gravida<br>
porttitor. Integer sed turpis arcu. Curabitur<br>
nec dolor urna, ac molestie neque. Nunc ac<br>
augue non mi imperdiet semper.
</div>
</div>
<div id="menuInfoTabs" class="menuTabs">
<div id="menuInfoTabShow" class="clickable tab showHide inActive hidden" onclick="tab(this.id);">
Show
</div>
<div id="menuInfoTabHide" class="clickable tab showHide inActive" onclick="tab(this.id);">
Hide
</div>
<div id="menuInfoTab1" class="clickable tab secondary active" onclick="tab(this.id);">
1
</div>
<div id="menuInfoTab2" class="clickable tab secondary inActive" onclick="tab(this.id);">
2
</div>
</div>
</div>
</div>
</div>
<script type='text/javascript' src='./script.js'></script>
</body>
</html>
CSS
/* removes the top and left whitespace */
* { margin:0; padding:0; }
/* ensure full screen */
html, body {
width:100%;
height:100%;
font-family: "Courier New", Courier, monospace;
font-size: 95%;
}
/* remove the scrollbars */
canvas {
display:block;
}
#menuCtrl {
position: absolute;
margin: 5px;
}
#menuInfo {
position: absolute;
bottom: 0;
right: 0;
margin: 5px;
}
.menuWrapper {
}
.menuForm {
float: left;
margin-top: 22px;
padding: 5px;
background-color: white;
border: 2px solid black;
border-radius: 10px;
border-top-left-radius: 0;
box-shadow: 3px 3px 5px #333;
}
.menuForm table {
padding-top: 3px;
}
.menuForm td, th {
white-space: nowrap;
}
.menuForm th {
text-align: left;
}
.menuTabs {
position: absolute;
white-space: nowrap;
top: 0;
}
.menuTabs div.tab {
float: left;
height: 20px;
min-width: 20px;
margin: 0;
padding: 0 5px 0 5px;
text-align: center;
background-color: white;
border: 2px solid black;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
.menuTabs div.secondary {
border-left: 0px;
}
.menuTabs div.active {
opacity: 1;
border-bottom: 2px solid white;
}
.menuTabs div.active.showHide {
border-bottom: 2px solid black;
}
.menuTabs div.inActive {
opacity: .75;
border-bottom: 2px solid black;
}
.clickable {
cursor: pointer;
}
.visible {
text-decoration: underline;
text-decoration-color: black;
}
.invisible {
text-decoration: line-through;
text-decoration-color: red;
}
.hidden {
display: none;
}
Please try the following: http://jsfiddle.net/bQ6vZ/1/.
Is that performing as you desire?
I added the following CSS rules:
#menuInfoWrapper.hidden {
display: block;
}
#menuInfoWrapper.hidden #menuInfoTabs {
top: auto;
bottom: 0;
right: 0;
}
And added two lines to the JS, namely the hide('menuInfoWrapper'); and show('menuInfoWrapper'); lines seen below:
else if(id == 'menuInfoTabHide') {
hide('menuInfoTab1');
hide('menuInfoTab2');
hide('menuInfoFormDiv');
hide('menuInfoFormWrapper');
hide('menuInfoTabHide');
show('menuInfoTabShow');
}
else if(id == 'menuInfoTabShow') {
show('menuInfoTab1');
show('menuInfoTab2');
show('menuInfoFormDiv');
show('menuInfoWrapper');
hide('menuInfoTabShow');
show('menuInfoTabHide');
}
Hope this helps.
I would like to know if it possible to have a child element behind his parent element with z-index.
I would like to use the parent div as transparent color layer on top of his content.
Why not? Sure you can, and it's easy:
give a non-static position to your desired elements;
set z-index of child to -1;
create a stacking context on the main container (by setting on it a
z-index, opacity, transforms or whatelse generates a composite
layer).
.container {
position: absolute;
z-index: 0; /* or eg. opacity: 0.99;*/
background-color: blue;
color: lightblue;
width: 100%;
height: 100%;
text-align: center;
}
.parent {
position: relative;
background-color: rgba(100, 255, 150, 0.75);
color: green;
width: 50%;
height: 30%;
top: 30%;
left: 20%;
}
.child {
position: absolute;
z-index: -1;
background-color: orange;
color: yellow;
width: 100%;
height: 100%;
top: -50%;
left: 20%;
}
<div class="container">
<span>container</span>
<div class="parent">
<span>parent</span>
<div class="child">
<span>child</span>
</div>
</div>
</div>
(if the parent is used as a transparent layer, be sure to use a background-image or rgba background-color: children inherit the opacity of the parent)
The short answer is Yes ;)
There is an excellent article here that describes how you can use the stacking order of elements to allow the z-index to be negative in order to place an element behind it's parent.
http://philipwalton.com/articles/what-no-one-told-you-about-z-index/
Not possible, because each positioned element creates a stacking context.
Explanation 1, Explanation 2
You could just do it the other way and use the child as the overlay like this
HTML
<div id="stuff"><div class="overlay"></div>
<p>
Cras venenatis ornare tincidunt. Nam laoreet ante sed nibh pretium nec gravida turpis dapibus. Curabitur lobortis; lacus sit amet rutrum aliquet, est massa feugiat lectus, bibendum eleifend velit metus vitae dolor! Duis vulputate mi vitae quam fermentum pharetra.
</p>
</div>
CSS
#stuff{
position:relative;
}
.overlay{
width:100%;
height:100%;
position:absolute;
top:0;
left:0;
background:#ACA;
opacity:0.4;
}
While this wouldn't necessarily work in all browsers (especially older ones), the following has worked for me in the past:
#child {
position: relative;
z-index: -1;
...
}
I'm really only suggesting this as a last resort and would still prefer to use any technique other than this, although it might be ideal in your scenario.