demosthenes.info

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

featured articles

popular favourites

Lena Söderberg full colorLena Söderberg desaturated with CSS

Convert Images To Black And White With CSS

Filters allow us to visually process an image in the browser without needing to go through or use cycle-intensive, script-heavy methods in or PHP. 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 .

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 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 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.

You must be signed up in order to leave comments.

Nice article, very informative on how to achieve a grayscaled image over multiple browsers. But saying "even IE" seems a little harsh since you've been able to do this in IE for over a decade (since IE5.5). I know I'm going to get bashed for sticking up for IE.

posted by Fat Rick P

Dudley StoreyQuite correct, Rick - it was a little bit of a dig at Microsoft. They do deserve credit for being the first to feature such filters (way back in IE4!), but the way they implemented them was always so odd and proprietary, and only for Windows, that the Microsoft spec never really gained any popularity. I'm glad they're moving on to CSS3 standards!

posted by Dudley Storey

I found a small issue with the SVG code. This is probably assumed, but for those who don't know, you need to put the following code as the first line in the SVG file: <?xml version="1.0" encoding="UTF-8"?>

posted by Eric Tompkins

Other than the above issue your article was extremely helpful and gave us the solution that we needed. Thank you.

posted by Eric Tompkins

i was a bit thrown off by the spelling of #greyscale opposed to #grayscale in the svg filter. otherwise, this was excellent! thanks

posted by kmb00

Only three CSS properties are required for IE6-9, Firefox 3.5+, Chrome 19+ and Safari 6+. The HTTP request for the SVG can also be eliminated with a data-uri. See my blog post for more details:

img.grayscale {
filter:
url("data:image/svg+xml;utf8,#grayscale"); /* Firefox 3.5+ */
filter: gray; /* IE6-9 */
-webkit-filter: grayscale(100%); /* Chrome 19+ & Safari 6+ */ }

posted by karlhorky

Dudley StoreyNicely done, Karl! The only addition I'd make to your code is a catch-all filter: grayscale(100%); at the end of the declaration, for browsers that implement CSS filters without prefixes (as new versions will during the coming year).

posted by Dudley Storey

Thanks for Your Tip, The demo works like magic. But My problem is that I am using Wordpress and Its hard for me to achieve this. Any Help that will point me in the right direction, will be deeply appreciated. Thank You.

posted by Ink9oz

Dudley StoreyHi Ink: I'm afraid I haven't worked extensively with WordPress, so I'm not aware of a solution to your problem. Perhaps someone else might be able to contribute an answer?

posted by Dudley Storey

web developer guide

featured comment

by Aisling Brock in New Business Card Design

what i'm reading

A Feast for Crows: A Song of Ice and Fire: Book Four
A Feast for Crows: A Song of Ice and Fire: Book Four

what i'm watching

Prometheus: Collector's Edition (Bilingual) [Blu-ray 3D + Blu-ray + DVD + Digital Copy]
Prometheus: Collector's Edition (Bilingual) [Blu-ray 3D + Blu-ray + DVD + Digital Copy]

what i'm playing

Borderlands
Borderlands

what i'm hearing

Planets
Planets

blogs

podcasts

no ads ever

This blog is free of advertising, and always will be.

creative commons licensed

The content of this blog is free to use in whatever way you wish under the Creative Commons license.