Razzka Razzka - 3 months ago 15
HTML Question

Filter property on div affecting children

I have a

div
, which can contain several other divs, that can outstep parent's borders.

Parent
div
has a CSS filter
drop-shadow


-webkit-filter: drop-shadow(5px 5px 5px green);
filter: drop-shadow(5px 5px 5px green);


So, all children also generate parent's shadow.

Is it possible to mark one of the children
divs
not render the filter drop shadow?

Unortunately, I can't move this div outside parent.

Here's plunkr with a simple example :



.greenBorder {
width: 50px;
height: 50px;
border-radius: 10px;
background: black;
-webkit-filter: drop-shadow(5px 5px 5px green);
-moz-filter: drop-shadow(5px 5px 5px green);
-ms-filter: drop-shadow(5px 5px 5px green);
-o-filter: drop-shadow(5px 5px 5px green);
filter: drop-shadow(5px 5px 5px green);
}
.withShadow {
position: absolute;
width: 50px;
height: 10px;
left: 30px;
top: 25px;
background: red;
border-radius: 5px;
}
.withoutShadow {
position: absolute;
width: 10px;
height: 50px;
left: 30px;
top: 25px;
background: blue;
border-radius: 5px;
/* Can this div ignore parent's filter and not generate shadow? */
-webkit-filter: none;
-moz-filter: none;
-ms-filter: none;
-o-filter: none;
filter: none;
box-shadow: none;
}

<div class="greenBorder">
<div class="withoutShadow"></div>
<div class="withShadow"></div>
</div>




Answer

This not possible.

In the Filter Effects Module Level 1 you can read:

A computed value of other than none results in the creation of a stacking context [CSS21] the same way that CSS opacity does. All the elements descendants are rendered together as a group with the filter effect applied to the group as a whole. [source: w3.org]

This means that all children are affected by by the filter property the same way opacity works.

Workaround :

If you can't change your makup, you can apply the filter only to the elements you need it on. In your example, you can replace the black background with a pseudo element and apply the drop shadow to that pseudo element. This will prevents applying the filter to the parent and affecting all the children

Example:

.greenBorder {
  position:relative;
  width: 50px;
  height: 50px;
  border-radius: 10px;
}
.greenBorder:before{
  content:'';
  position:absolute;
  top:0; left:0;
  width:100%; height:100%;
  background: black;
  border-radius:inherit;
  -webkit-filter: drop-shadow(5px 5px 5px green);
  -moz-filter: drop-shadow(5px 5px 5px green);
  -ms-filter: drop-shadow(5px 5px 5px green);
  -o-filter: drop-shadow(5px 5px 5px green);
  filter: drop-shadow(5px 5px 5px green);
}

.withShadow {
  position: absolute;
  width: 50px;
  height: 10px;
  left: 30px;
  top: 25px;
  background: red;
  border-radius: 5px;
  -webkit-filter: drop-shadow(5px 5px 5px green);
  -moz-filter: drop-shadow(5px 5px 5px green);
  -ms-filter: drop-shadow(5px 5px 5px green);
  -o-filter: drop-shadow(5px 5px 5px green);
  filter: drop-shadow(5px 5px 5px green);
}

.withoutShadow {
  position: absolute;
  width: 10px;
  height: 50px;
  left: 30px;
  top: 25px;
  background: blue;
  border-radius: 5px;
}
<div class="greenBorder">
  <div class="withoutShadow"></div>
  <div class="withShadow"></div>
</div>