I'm Dudley Storey, the author of Pro CSS3 Animation. This is my blog, where I talk about web design and development with HTML, CSS and SVG. To receive more information, including news, updates, and tips, you should follow me on Twitter or add me on Google+.

my books

Pro CSS3 Animation, Apress, 2013

Using SVG with CSS3 and HTML5, O'Reilly, 2017

my other blogs

Massive Head Canon: Intelligent discussion of movies, books, games, and technology.

my projects

The New Defaults — A Sass color keyword system for designers. Replaces CSS defaults with improved hues and more memorable, relevant color names.

CSSslidy — an auto-generated #RWD image slider. 3.8K of JS, no JQuery.

Convert Images To Black And White With CSS

A cross-browser color-to-greyscale photographic effect with CSS & SVG

Filters allow us to visually process an image in the browser without needing to go through PhotoShop or use cycle-intensive, script-heavy methods in JavaScript or PHP. CSS3 filters are broadly supported in the most recent versions of Firefox, Safari and Chrome, and we can gain support in older versions and alternative browsers – even IE –  by using a combination of techniques.

In this article we’ll convert an image to black & white with pure CSS using the classic test image of Lena Söderberg. In future articles I’ll discuss how to achieve sepia toning, blurring, brightness, contrast and other visual effects with CSS.

The CSS3 greyscale filter

Desaturating a color image couldn’t be simpler with CSS3. We’ll apply the filter as a class, as you’d typically desire several images to be affected by the code at the same time:

  1. img.desaturate { filter: grayscale(100%); }

Naturally, all current browsers implement CSS3 filters via vendor prefixes, so our first job is to insert that code, writing in CSS that does not yet exist in order to future-proof our work:

  1. img.desaturate { filter: grayscale(100%);
  2. -webkit-filter: grayscale(100%);
  3. -moz-filter: grayscale(100%);
  4. -ms-filter: grayscale(100%);
  5. -o-filter: grayscale(100%);
  6. }

Applying the class to the image is easy:

  1. <img src=lena-söderberg.png alt="Lena Söderberg"
  2. style=width:512px;height:512px class=desaturate>

Add An SVG Filter Effect

The CSS shown to this point works only in Chrome 18+, with support in other browsers expected to arrive soon. To gain the same effect in Firefox 4+, we need to use an SVG filter, which I’ll create as a separate document named desaturate.svg. The code for that file will be:

  1. <svg version="1.1" xmlns="http://www.w3.org/2000/svg">
  2. <filter id="greyscale">
  3. <feColorMatrix type="matrix" values="0.3333 0.3333 0.3333 0 0
  4. 0.3333 0.3333 0.3333 0 0
  5. 0.3333 0.3333 0.3333 0 0
  6. 0  0  0  1 0"/>
  7. </filter>
  8. </svg>

If the SVG code looks slightly daunting – and the matrix math behind it is somewhat complex – don’t worry. This is one piece of code that I’d actually encourage you to copy and paste as a generic “recipe”. I’ll explain matrix transformations in a future article.

With the SVG file saved beside our HTML page and test image, we will extend the CSS to become:

  1. img.desaturate{
  2. filter: grayscale(100%);
  3. -webkit-filter: grayscale(100%); -moz-filter: grayscale(100%);
  4. -ms-filter: grayscale(100%); -o-filter: grayscale(100%);
  5. filter: url(desaturate.svg#greyscale);
  6. }

Add Support for IE

So far our code covers future browsers, recent versions of Chrome and Firefox 4+. To include IE 6 – 9, we'll apply Microsoft’s simple but proprietary use of filter:

  1. img.desaturate{
  2. filter: grayscale(100%);
  3. -webkit-filter: grayscale(100%); -moz-filter: grayscale(100%);
  4. -ms-filter: grayscale(100%); -o-filter: grayscale(100%);
  5. filter: url(desaturate.svg#greyscale);
  6. filter: gray;
  7. }

If you want to add in support for older versions of Webkit:

  1. img.desaturate{
  2. filter: grayscale(100%);
  3. -webkit-filter: grayscale(100%); -moz-filter: grayscale(100%);
  4. -ms-filter: grayscale(100%); -o-filter: grayscale(100%);
  5. filter: url(desaturate.svg#greyscale);
  6. filter: gray;
  7. -webkit-filter: grayscale(1);
  8. }

Unfortunately Safari and Opera are still left out of the picture, but Safari 5.2 – due to be released very soon – should support the –webkit CSS3 filter prefix, and Opera’s support for CSS3 is continuing to improve.

The CSS we've written here allows us to visually convert an image to black and white on the fly in our browser, with no need to save new versions in PhotoShop. Using CSS also makes the image much easier to modify: for example, you’ll see that lowering the percentage used in our declaration from 100% to 50% causes a visual blend of the desaturation effect with the original color image.

This site helps millions of visitors while remaining ad-free. For less than the price of a cup of coffee, you can help pay for bandwidth and server costs while encouraging further articles.