11

I have problem with my css code.

As you see I have filter on li element, but it's overlays other elements. I need to make other two elements had no filter:

Is there any possibility to do so.

.main {
  width:300px;
  height:300px;
  background-color:blue;
  list-style:none;
}

.button {
    position: absolute;
    top: 35% ;
    height: 30px;
    width: 120px;
    display: none;
    z-index: 99;
    background-color:black;
    color:white;
}

.icon {
    width: 30px;
    position: absolute;
    z-index: 99;
    display: none;
    width:100px;
}

.main:hover > .button {
    display: block;
    filter: none;
}

.main:hover > .icon {
    display: block;
    filter: none;
}

.main:hover {
    filter: brightness(50%);
    transition: 0.5s;
}
<li class="main">
<img src="https://help.seesaw.me/hc/en-us/article_attachments/204081043/bear.png" class="icon" />
<a class="button" href="#">Button</a>
</li>
Sergi Khizanishvili
  • 537
  • 1
  • 7
  • 16
  • you cannot do it like this, it's like opacity, display,etc .. filter on parent apply on childs – Temani Afif Jul 03 '18 at 12:05
  • Nope, you can't do that. The `filter` applies to all child elements because of how it's composited: think of something like `opacity`. You cannot "reverse" the opacity of a child element. If you want to isolate the filter, you will have to change how your markup is written. – Terry Jul 03 '18 at 12:05

3 Answers3

6

The only way to do this is to revert the filter on the child.

For example, if the parent has:

filter: invert(100%);

then applying this filter to the child will reverse the effect:

filter: invert(100%);

Note that if you have multiple filters, the order of filters is important!

In this way the filter will be applied to all children EXCEPT the ones to which you apply the reversed filter.

.parent {
  filter: invert(100%);
}

.child, .no-parent-with-no-filters {
  width: 100px;
  height: 100px;
  border: 5px solid green;
  background-color: blue;
  float: left;
}

.child2 {
  filter: invert(100%);
}
<div class="parent">
  <div class="child child1">filter on parent</div>
  <div class="child child2">filter on parent but reverted</div>
  <div class="child child3">filter on parent</div>
</div>

<div class="no-parent-with-no-filters">no filters</div>

For more complex filter combinations reverting is more difficult. As a start, check out this question for more info:

halfer
  • 19,824
  • 17
  • 99
  • 186
danday74
  • 52,471
  • 49
  • 232
  • 283
5

You can't do it that way. Childs are affected by their parent style.
That's how Cascading Style Sheets works.

I suggest you to use a pseudo-element to make it work like you want, so that only the pseudo-element would be affected.

See comments in the snippet:

.main {
  position: relative;   /* Added */
  width: 300px;
  height: 300px;
  list-style: none;
}

.main::before {   /* Added */
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: blue;
  transition: 0.5s;
}

.button {
  position: absolute;
  top: 35%;
  height: 30px;
  width: 120px;
  display: none;
  z-index: 99;
  background-color: black;
  color: white;
}

.icon {
  width: 30px;
  position: absolute;
  z-index: 99;
  display: none;
  width: 100px;
}

.main:hover>.button {
  display: block;
  /* filter: none; Commented */
}

.main:hover>.icon {
  display: block;
  /* filter: none; Commented */
}

.main:hover::before {   /* Modified */
  filter: brightness(50%);
}
<li class="main">
  <img src="https://help.seesaw.me/hc/en-us/article_attachments/204081043/bear.png" class="icon" />
  <a class="button" href="#">Button</a>
</li>

Hope it helps.

Takit Isy
  • 9,688
  • 3
  • 23
  • 47
0

I'll suggest pseudo-element for this task. Your .main class retains the parent position with position:relative, While the image and button, becomes dependant with a position absolute. On hover on the element with .main class, add the pseudo-element ::before and apply the necessary styles as stated in code below.

.main {
  width:300px;
  height:300px;
  list-style:none;
  position:relative;
  background-color:blue;
}

.button {
    position: absolute;
    top: 35% ;
    height: 30px;
    width: 120px;
    display: none;
    z-index: 99;
    background-color:black;
    color:white;
}

.icon {
    width: 30px;
    position: absolute;
    z-index: 999999;
    display: none;
    width:100px;
}

.main:hover>.button {
  display: block;
}

.main:hover>.icon {
  display: block;
}

.main:hover::before {
  content: "";
  top: 0;
  bottom: 0;
  right: 0;
  left: 0;
  position:absolute;
  background-color:blue;
  transition: 0.5s;
  filter: brightness(50%);
}
<li class="main">
<img src="https://help.seesaw.me/hc/en-us/article_attachments/204081043/bear.png" class="icon" />
<a class="button" href="#">Button</a>
</li>
JideLambo
  • 91
  • 3