Grayscale only button background but not text [duplicate] - css

This question already has answers here:
How to apply a CSS filter to a background image
(22 answers)
Closed 2 years ago.
I have several buttons with different background images.
I would like to achieve to have a grayscale filter on them by default and on hover remove the grayscale filter.
I have this already but the problem is that the text of the buttons are also grayed out which i would like to avoid.
I Couldn't figure out how to apply grayscale filter only on button backgrounds but not on text.
Now I have a main css class for the buttons
.box {
-webkit-filter: grayscale(100%);
filter: grayscale(100%);
position:relative;
color: red;
cursor:pointer;
text-align: center;
width: 160px;
height: 160px;
}
.box:hover {
-webkit-filter: grayscale(0%);
filter: grayscale(0%);
color: blue;
}
and I apply the backgrounds for each button in html code
<button onclick="buttonFunction()" button class="button box" style="background: url(background1.jpg); background-size: 100%;" >Gray button text:( </button>
Any idea how to add grayscale filter only button backgrounds and keep the button texts colored?
Thanks

Applying the filter property to an element will affect the children of that element. You will not be able to unset / reset the filter property for the children.
If you don't want to / can't use the pseudoelement approach in the other answers, then you could change your HTML to create the effect you want.
Add the image as an img element in the button, and place the text in a span. You can then apply the filter to the img.
.box {
cursor: pointer;
width: 160px;
height: 160px;
position: relative;
padding: 0;
display: inline-flex;
justify-content: center;
align-items: center;
}
.box img {
-webkit-filter: grayscale(100%);
filter: grayscale(100%);
position: absolute;
max-width: 100%;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
.box:hover img {
-webkit-filter: grayscale(0%);
filter: grayscale(0%);
}
.text {
color: red;
z-index: 1;
}
.box:hover .text {
color: blue;
}
<button onclick="buttonFunction()" button class="button box"><img src="https://unsplash.it/200x200"><span class="text">Gray button text:(</span></button>

As Temani Afif also points out pseudo elements are your way to go although I would like to add a bit different way of positioning which I believe might be more precise and more easy to adapt to a responsive design.
The key part is making the .box have the same height and line-height which will also be the height of our :after content. Then the absolute positioning (0-0-0-0) will center it automatically.
.box {
position: relative;
color: #ff0000;
text-align: center;
width: 300px;
height: 300px;
line-height:300px;
}
.box:before {
content: ' ';
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
filter: grayscale(100%);
background: url(https://upload.wikimedia.org/wikipedia/commons/thumb/e/e9/16777216colors.png/220px-16777216colors.png);
background-size: cover;
}
.box:hover:before {
filter: grayscale(0%);
}
.box:after {
content: 'Text Text Text';
position: absolute;
left:0;
bottom:0;
right:0;
top:0;
display: inline-block;
vertical-align: middle;
}
<button type="button" class="box">Button</button>

Related

CSS | Blur behind image

I use this loader spinner using css and jquery. I would like to blur the background exept the image from URL. Any idea ?
Css:
.no-js #loader { display: none; }
.js #loader { display: block; position: absolute; left: 100px; top: 0; }
.se-pre-con {
position: fixed;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
z-index: 1;
background: url("http://enjoycss.com/bg-img/custom/107898-1py1ieu.1zm9.gif")
center no-repeat #33333308;
}
Js
<script>
$(window).load(function() {
$(".se-pre-con").fadeOut("slow");;
});
</script>
Thank you
When the gif is showing you can add a :before pseudo-element to the body. The blurry effect can be tricky to achieve, I'd recommend using a blurry PNG or a svg as background, in the snippet below I'm just using color:
body:before{
content:'';
background-color: #dbdbdb;
opacity: 0.7;
background-size: cover;
width: 100%;
padding-bottom: 100%;
position: fixed;
z-index: 1;
}
You can replace the body selector with a class and then with some jQuery remove or add the class to the body.
See this fiddle for reference: https://jsfiddle.net/3r1zc9gw/3/

How to get a background color low opacity overlay on a featured image? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
He everyone i am strugling to find a css that will work to get a overlay on my feautured image so you can see my title more clear. For the site www.quinstudio.nl/gallery. Any idea how i can get this to work?
? {
background: #000;
opacity: .1;
}
There are several ways you could approach this. There's no real difference in how they'll turn out; you can use whichever works better with the markup you have. The first option is a little simpler because there's no empty div being added as a color overlay.
Option 1: Make the colored background opaque, and the image partially transparent.
.image-wrapper {
display: inline-block;
background: #0cd;
/* You need this line for the centered h1 below to work. */
position: relative;
}
.image-wrapper img {
opacity: 0.5;
display: block;
}
.image-wrapper h1 {
/* Here's a trick for centering your title, if you want. */
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
margin: auto;
color: #fff;
}
<div class="image-wrapper">
<img src="https://loremflickr.com/320/240" alt="Kitten">
<h1>Kitty!</h1>
</div>
Option 2: Make the image opaque, and put a partially transparent overlay on top of it.
.image-wrapper {
display: inline-block;
position: relative;
}
.image-wrapper img {
display: block;
}
.image-overlay {
background: #000;
opacity: 0.5;
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
z-index: 2; /* puts this div 'in front' of the image */
}
.image-wrapper h1 {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: #fff;
z-index: 3; /* puts the text in front of the dark overlay */
}
<div class="image-wrapper">
<img src="https://loremflickr.com/320/240" alt="Kitty!">
<div class="image-overlay"></div>
<h1>Kitty?</h1>
</div>
While #jack's answer is good, I'd like to share an alternative one that doesn't use an <img> element and instead uses the :after pseudo-element.
This allows you to use the CSS background image on the container and essentially add a fake element that has the color overlay on it:
.container {
background: url(https://loremflickr.com/320/240);
width: 320px;
height: 240px;
position: relative;
}
.overlay > * {
z-index: 1;
position: relative;
color: #fff;
}
.overlay:after {
content: "";
background: #0095ee;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
opacity: .65;
}
<div class="overlay container">
<h1>Title</h1>
</div>
Edit:
Your situation is a little different. You can just lower the opacity of the image and add a black background to it's parent container. Try the following:
.edgt-justified-layout .edgt-ni-inner .edgt-ni-image-holder .edgt-post-image img {
opacity: .75;
}
.edgt-justified-layout .edgt-ni-inner .edgt-ni-image-holder .edgt-post-image {
background: #000;
}
It will lower the opacity of the image (which will make it look "whiter", so we can add a black (or whatever color you want) background to it's parent container to compensate and darken it instead.

Why are my pseudo-classes overriding display:none?

I have a div that appears as an "X" (used to close a window):
<div class="alertwrapper" style="display:inline-block;">
<div class="obj"></div>
<div class="x"></div> //<-----ELEMENT IN QUESTION
</div>
The following are the CSS properties of this element:
.x {
display: none !important;
position: absolute !important;
left:0;
top:0;
transition: transform .25s ease-in-out;
z-index:999;
}
.x:before {
content: "";
position: absolute;
//Here, I've also tried display:none !important;
left: 48%;
margin-left:-495px;
right: 0;
top: 115px;
bottom: 0;
width: 32px;
height: 0;
border-top: 3px solid black;
transform: rotate(45deg);
transform-origin: center;
z-index:999;
}
.x:after {
content: "";
position: absolute;
//Here, I've also tried display:none !important;
left: 48%;
margin-left:-495px;
right: 0;
top: 115px;
bottom: 0;
width: 32px;
height: 0;
border-top: 3px solid black;
transform: rotate(-45deg);
transform-origin: center;
z-index:999;
}
This div should not be displayed until another element is clicked, at which point, it should appear, as defined by the following code:
<script type="text/javascript">
$(document).ready(function () {
$('body').on('click', '.ActiveQuestionCycler', function() {
$("div.x").fadeIn(300).delay(1500);
$("div.obj").fadeIn(300).delay(1500);
});
});
</script>
When the page loads, however, the div "x" is visible, before .ActiveQuestionCycler is clicked. (The display is not set to none.) I think this has to do with the pseudo-classes before and after overriding this but I can't figure out why.
(div.obj DOES fade in when .ActiveQuestionCycler is clicked.)
There are no error alerts in the source.
This comment /// STYLE SETTINGS FOR THE QUESTION CONTAINER AND CLOSE "X" BUTTON on line 109 is invalid. Change it to:
/* STYLE SETTINGS FOR THE QUESTION CONTAINER AND CLOSE "X" BUTTON */
and it should work. Remember to drop that display: none; into the .x
So it will look like:
.x {
display: none;
/* your other styles */
}
While // comment is normal for most programming languages, regular css does not accept it and css comments go like this /* comment */

css transparent shape over image

This is what i am trying to achive
i have :
#image1 {
position: absolute;
bottom: 0px;
align-self: auto;
background-color: #dc022e;
width: 340px;
height: 100px;
border-radius: 50% / 100%;
border-bottom-left-radius: 0;
/*transform: rotate(10deg);*/
border-bottom-right-radius: 0;
opacity: 0.8;
}
#image2 img {
width: 80%;
}
<div>
<div id="image2">
<img src="http://t1.gstatic.com/images?q=tbn:ANd9GcThtVuIQ7CBYssbdwtzZjVLI_uw09SeLmyrxaRQEngnQAked5ZB">
</div>
<div id="image1"></div>
</div>
Finally I don't know how to make it rotated and with the margins cut like in the picture
A Quick example of this would use a pseudo element and have the image set in the background.
div {
position: relative;
height: 300px;
width: 500px;
background: url(http://lorempixel.com/500/300);/*image path*/
overflow: hidden;/*hides the rest of the circle*/
}
div:before {
content: "";
position: absolute; /*positions with reference to div*/
top: 100%;
left: 50%;
width: 0;/*define value if you didn't want hover*/
height: 0;
border-radius: 50%;
background: tomato;/*could be rgba value (you can remove opacity then)*/
opacity: 0.5;
transform: translate(-50%, -50%);/*ensures it is in center of image*/
transition: all 0.4s;
}
/*Demo Only*/
div:hover:before {/*place this in your pseudo declaration to remove the hover*/
height: 100%;
width: 150%;/*this makes the shape wider than square*/
transform: translate(-50%, -50%) rotate(5deg);/*ensures it is in center of image + rotates*/
}
div {/*This stuff is for the text*/
font-size: 40px;
line-height: 300px;
text-align: center;
}
<div>HOVER ME</div>
Instead of nested elements, you can just use a pseudo element. This is placed at the bottom of the container div. For this to work, you need position:relative and overflow:hidden on the container div. Also, pseudo elements always need the content declaration.
To modify the border radius, you just play around with left | width | height of the pseudo element. You don't need any rotation.
Instead of hex color and opacity you can as well use the "new" color space rgba(r,g,b,a) where a is the opacity value.
For the passepartout you simply use the border declaration.
#image2{
position:relative;
border:10px solid #888;
overflow:hidden;
box-shadow:0 0 4px #aaa;
}
#image2::after {
content:"";
display:block;
position: absolute;
bottom: 0;left:-10%;
background-color: #dc022e;
width: 120%;
height: 60%;
border-radius: 100% 100% 0 0;
opacity: 0.8;
}
#image2 img {
width: 100%;
display:block;
position:relative;
}
<div id="image2">
<img src="http://t1.gstatic.com/images?q=tbn:ANd9GcThtVuIQ7CBYssbdwtzZjVLI_uw09SeLmyrxaRQEngnQAked5ZB">
</div>
You can just use position: absolute for your image and position: relative for your overlay, adjusting the top position and width according to your needs. Here's a Fiddle. Hope this helps!
Edit: Here's an updated version of the Fiddle demonstrating border and overflow properties on the img container. As CBroe mentioned, rotating a circle is probably not a good use of your time in this case. Also, I definitely agree that using a pseudo element is a much cleaner approach than nesting images.

Grayscale image with colored border

I need to put a set of b/w images with colored borders on the page. I don't want to edit the images in Photoshop, since there may be some dynamically added ones later on; hence, I've used the corresponding filter:grayscale(100%).
img.myImage {
display: block;
position: relative;
border: 6px solid #0090ff;
width: 85%;
margin: 0 auto;
-webkit-filter: grayscale(100%);
filter: grayscale(100%);
}
However, it affects the colored border, which also becomes grayish. Is there a "painless" workaround here?
Since img does not accept :after/:before, and since filter seems to apply on children elements, the only solution I can think of is the basic:
div {
display: inline-block;
background-color: #0090ff;
padding: 6px;
width: 200px;
}
img {
display: block;
-webkit-filter: grayscale(100%);
filter: grayscale(100%);
width: 100%;
}
<div>
<img src="https://pbs.twimg.com/profile_images/562466745340817408/_nIu8KHX.jpeg" alt="" />
</div>

Resources