You can take a normal coloured image and make it gray by applying a grayscale to it by adding a few lines of CSS. This is achieved using the CSS3 filter property. A common use case for making images gray is for client logos, like I have done on my client services site.

What is a filter?

A filter allows you to modify an image in CSS3 without having to change the actual image in a graphics application like Photoshop or Pixelmator. Spending less time adjusting images in Photoshop is a win in my book!

The syntax for the filter property is as follows:

filter: filter(value);

The filter can be used for blur, sepia, contrast as well as grayscale (and more).

The grayscale filter

filter: grayscale(100%);

You can control how much the image is filtered by changing the value. Completely gray is 100%. 0 would leave the image unchanged. You can choose something inbetween. For example, 50% is half way between the original colour and completely gray, which gives it a desaturated effect.

This will work for Firefox 35+. Unfortunately this is not widely supported by other browsers, so we need to add in browser specific code.

Adding in the webkit browser prefix:

 -webkit-filter: grayscale(100%);

This will work in Chrome 18+ and Safari 6+ (more info on supported browsers on the Mozilla Developer Network ).

Up to Firefox 35

This won’t work on Firefox before version 35. For it to work on Firefox, we need to use the SVG filter instead.

 filter: url("data:image/svg+xml;utf8,<svg version='1.1' xmlns='http://www.w3.org/2000/svg' height='0'><filter id='greyscale'><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>#greyscale");

Above snippet from Dudley Storey

Internet Explorer

IE 6 to 9 uses a proprietary version of filter.

 filter: gray; 

Unfortunately this technique won’t work at all for IE 10+. This is because Microsoft dropped their proprietary version of filter but are yet to implement the standard CSS3 one (thanks Microsoft!). If you want to make it work for IE10+ you’ll need to use a Javascript solutions like Grayscale.js

Old versions of Webkit

You can support older versions of Webkit (Chrome and Safari) by using a 0 to 1 scale rather than percentage. For example, to be 100% gray, use 1.

-webkit-filter: grayscale(1); /* Old WebKit */

Putting it all together

Here is the full snippet:

filter: grayscale(100%); /* Standard */
-webkit-filter: grayscale(100%); /* Webkit */
filter: url("data:image/svg+xml;utf8,<svg version='1.1' xmlns='http://www.w3.org/2000/svg' height='0'><filter id='greyscale'><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>#greyscale"); /* Firefox4-34*/
filter: gray;  /* IE6-9 */
-webkit-filter: grayscale(1); /* Old WebKit */

Full colour on hover

A nice effect is to remove the filter when hovering over the image. To do that, simply use none to both -webkit-filter and filter.

img:hover {
    -webkit-filter: none;
    filter:none;
}