CSS on Parent Hover Keep Child Not Filter-Grayscaled

Make a parent div webkit-filter not affect children

This is not a problem of properties inheritance, as you can think.

The way filters work makes that imposible to fix changing attributes in the CSS: The element affected by the filter is rendered, all the children are rendered, and then the result (as an image) has the filter applied.

So the only alternatives left are:

1) Change the HTML, as Lowkase suggested

2) In your case, seems that all you want to make gray is the background image. In this case, you can leave the HTML as is, display the image in a pseudo element, and apply the filter to this pseudo element.

CSS

.cell{
opacity:0.7;
width:420px;
height:420px;
transition: opacity .3s ease-in-out;
-moz-transition: opacity .3s ease-in-out;
-webkit-transition: opacity .3s ease-in-out;
}

.A1 {
position: relative;
}
.A1:before {
content: "";
position: absolute;
width: 100%;
height: 100%;
top: 0px;
left: 0px;
background-image:url('http://i.imgur.com/NNKxZ5R.jpg');
filter: url(filters.svg#grayscale); /* Firefox 3.5+ */
filter: gray; /* IE6-9 */
-webkit-filter: blur(15px); /* Google Chrome, Safari 6+ & Opera 15+ */
z-index: -1;
}

#text {
color:#ffffff;
text-align:center;
font:18px sans serif;
text-decoration:none;
}
.cell:hover {
opacity:1.0;
}

.A1:hover:before {
filter: none;
-webkit-filter: grayscale(0);
transition: opacity .3s ease-in-out;
-moz-transition: opacity .3s ease-in-out;
-webkit-transition: opacity .3s ease-in-out;
}

fiddle

I have also changed your filter to blur to make it more clear the the text is not affected by the filter. Since you had also some opacity set, the text still looked grayish just because you were seeing the gray under it.

Added example using brightness filter (for webkit)

demo 2

Remove CSS filter on child elements

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>

How to blur(css) div without blur child element

How to disable blur on child element?

.enableBlur>* {  filter: blur(1.2px);}
.disableBlur { filter: blur(0);}
<div class="enableBlur">  <hr>  qqqqq<br>  <span>qqqqq</span><br>  <hr  class="disableBlur">  <div>aaaaa</div>  <div>bbbbb</div>  <div class="disableBlur">DDDDD</div>  <hr>  <img src="https://lh5.googleusercontent.com/-n8FG4f09-ug/AAAAAAAAAAI/AAAAAAAACmA/ldtxmWX1SyY/photo.jpg?sz=48">  <img class="disableBlur" src="https://lh5.googleusercontent.com/-n8FG4f09-ug/AAAAAAAAAAI/AAAAAAAACmA/ldtxmWX1SyY/photo.jpg?sz=48"></div>

webkit-filter grayscale doesnt work

Your code above is perfectly sound, and does indeed make an image turn grey upon hover. Keep in mind that your selector div.img2:hover is applying the hover to a <div>, and that <div> needs to have a class of img2. The <div> would need to have a child <img> in order to showcase the hover.

It's possible that you were applying the class to the image instead (with <img class="img2">), and meant to write div .img2 (with a space). The space here indicates that the selector should target any elements with a class of .img2 that are a child of <div>.

Here you can see the CSS working as written in the original question:

div.img2 {  background: position: absolute;  top: 0%;  left: 0%;  transition: grayscale 2s ease;  -webkit-transition: grayscale 2s ease;}
div.img2:hover { filter: grayscale(100%); -webkit-filter: grayscale(100%);}
<div class="img2">  <img src="https://www.w3schools.com/css/img_fjords.jpg"></div>

Why does stacking order change on webkit filter hover?

This is because a value other than none establishes a stacking context. This is documented in the spec (which is currently in Working Draft status):

2 Module interactions

This specification defines a set of CSS properties that affect the
visual rendering of elements to which those properties are applied;
these effects are applied after elements have been sized and
positioned according to the Visual formatting model from [CSS21]. Some
values of these properties result in the creation of a containing
block, and/or the creation of a stacking context
.

Also the spec states:

5 Graphic filters: the filter property

A computed value of other than none results in the creation of a
stacking context
[CSS21] the same way that CSS opacity does.



Related Topics



Leave a reply



Submit