Reputation: 7105
I tried using this technique
<div class="grayscale"><span style="color:red">Red Text</span>
.grayscale {
background: url(yourimagehere.jpg);
-moz-filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#grayscale");
-o-filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#grayscale");
-webkit-filter: grayscale(100%);
filter: gray;
filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#grayscale");
}
It works well on background image, but also greys out all contents of the box. Is there any way to grey background only but keep contents full color? Thanks!
Upvotes: 3
Views: 3587
Reputation: 1676
It's possible, as seen here
You'll need to make your background image as the :before
element, then the greyscale filter won't be applied to the children.
HTML
<div class="module">
<div class="module-inside">
Module
</div>
</div>
CSS
body {
height: 100vh;
padding: 0;
display: grid;
align-content: center;
justify-content: center;
}
.module {
width: 300px;
height: 300px;
display: grid;
place-items: center;
color: #ff43ea;
position: relative;
}
.module::before {
content: "";
top: 0;
left: 0;
width: 100%;
height: 100%;
position: absolute;
background-image: url(https://images.unsplash.com/photo-1494645009625-cc17363a5f20?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ&s=bd502af39c922553e5a13624d4f44f40);
background-size: cover;
filter: grayscale(100%);
}
.module-inside {
position: relative;
font: bold 42px sans-serif;
}
Example: https://codepen.io/chriscoyier/pen/GXeQyJ
Upvotes: 1
Reputation: 1075
It's almost what @chris said. Taken from http://dev.w3.org/fxtf/filters/:
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.
You can, for instance, take the text out of your div and place it with absolute positioning.
Upvotes: 0
Reputation: 1184
You are applying the greyscale to the entire div with the class greyscale. This means that everything inside the div will comply. Therefore, you need to take your content (the span) out of the greyscale div and use css positioning to overlay the content on the image.
Upvotes: 0