How to Change the Color of an Image With CSS
Just because you got an image in a certain color doesn’t mean it has to stay that way
Imagine you receive a specific image from the product team that is meant to act as an icon for a button. The button has a white background, black border, black text, and the image itself is darker.
The CSS for this element can be seen below:
When the user hovers over the button, the desired behavior is that the background color changes to black, the font turns white, and the image is also white.
border changes when the user hovers over the button are straightforward. You can declare these updated styles under the
:hover selector in your stylesheet:
These styles take care of most of the changes, but they do not account for the image color change. How can we handle the expected change?
If the product team was kind enough to also provide a white version of the image, you can simply toggle the image’s
onmouseover function that sets the image’s
white.png and then an
onmouseleave function that sets the image’s
This works, but we can actually accomplish this task with pure CSS. This, however, would require including another element to wrap the image in. By having a wrapper for the image, you can assign the
background-image property either
white.png depending on if you’ve hovered over it or not:
For more on how to use CSS to change an image’s
src on hover, see this thread on Stack Overflow.
While this solution does work, you still need to add more HTML and it only works if you were fortunate enough to get a second asset. What if you only want to use CSS, no additional markup, and you don’t want to have to rely on the product team for another asset? Can it be done? Yes. Yes, it can.
filter CSS property, it’s easy to take our existing image and alter its coloration to fit our current needs. All we need to use is full grayscale and full inversion. See below:
-webkit-filter: grayscale(1) invert(1);
filter: grayscale(1) invert(1);
grayscale is a CSS function that converts the provided image to a grayscale, with
0 being the original (no grayscale change) and
1 being complete grayscale (makes it look more black and white). However, providing a grayscale to a black image will not make it look white. Darker colors are closer to black, while light colors are closer to white. So assigning a grayscale of
1 to a black image is almost redundant (we’ll get to that in a moment). This brings us to the next CSS function for
invert is a CSS function that inverts the color sample in the provided image, with
0 being the original and
1 being the opposite. Used in conjunction with
grayscale, we can make sure the image is as dark as possible, then invert the final scale to make it as light (in this case, white) as possible.
In our current case, you can actually just get away with using
Since our original asset is black, we don’t need to use
grayscale to make the image darker (as mentioned before, this is a bit redundant). A situation where grayscale might be more meaningful is when you have a contrasted image or at least an image that is not all black/white.
In the provided code sandbox below, you can see how
invert operate on an image with a bit more color (or dare I say, flair):