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
Twitter Bootstrap Text Field's Height Too Small
Firefox: How to Test Prefers-Color-Scheme
CSS: Style Applied to a Combination of Classes
How to Center an Image Horizontally and Align It to The Bottom of The Container
What Does an Underscore "_" Mean in CSS
How to Get a Negative Value with CSS Calc()
How to Combine Position: Relative and Float: Left
Flexbox with One Fixed Column Width
Svg Fill Color Not Working with Hex Colors
Bootstrap 3: Using Img-Circle, How to Get Circle from Non-Square Image
Scss/CSS Selector to Select All Input Types
Easy Tool to Decompose Sprite Image
Styling Not Applied to Vue Web Component During Development
Writing Flexbox Code for 2-Column and 3-Column on Desktop and Mobile (Wrap)
CSS Animation - Grow from Center (Zoom from Center Dot to Full Container)