Chroma: CSS-only image saturation animation

Special thanks to Karl Horky for the breakthrough with saturation filters for IE. This was an effect I had been implimenting with jQuery and the color.js plugin but the result was too reliant on codebase. This is a much smaller approach that works will in a lot of templating environments like Twitter Bootstrap, infact my intention was to controll the animation settings when declaring the element's class attribute. Chroma has a lightning-fast load time and looks great in most browsers. It degrades gracefully.

The default opacity is set to 0.6 and is configurable. I find that adding the opacity animation to the re-saturation effect helps to make the defaut state of the image integrate into the page better, regardless of background color. It also help to make the effect pop a bit, emphasising the color and making the animation more dynamic.

The saturation level, opacity, duration, and easing are all configurable and without the need to add code. Look for more filters and effects soon.

Image with 0.6s animation and linear easing

Simply add class of chroma6 to the img tag.

Profile pics with 0.2s animation and ease-out

Simply add class of "chroma2 ease-out" to the img tag.

The Code:

img[class*="filter-resat"] {
    filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><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>#grayscale");
    filter: gray;
    -webkit-filter: grayscale(100%);
    -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=60)";
    filter: alpha(opacity=40);
    -moz-opacity: 0.6;
    -khtml-opacity: 0.6;
    opacity: 0.6;
    -webkit-transition: all 1.0s ease;
    -webkit-backface-visibility: hidden;
}

img[class*="filter-resat"]:hover {
    filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'grayscale\'><feColorMatrix type=\'matrix\' values=\'1 0 0 0 0, 0 1 0 0 0, 0 0 1 0 0, 0 0 0 1 0\'/></filter></svg>#grayscale");
    -webkit-filter: grayscale(0%);
    -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
    filter: alpha(opacity=100);
    -moz-opacity: 1;
    -khtml-opacity: 1;
    opacity: 1;
}

img.chroma9 {-webkit-transition: all .9s ease;}
img.chroma8 {-webkit-transition: all .8s ease;}
img.chroma7 {-webkit-transition: all .7s ease;}
img.chroma6 {-webkit-transition: all .6s ease;}
img.chroma5 {-webkit-transition: all .5s ease;}
img.chroma4 {-webkit-transition: all .4s ease;}
img.chroma3 {-webkit-transition: all .3s ease;}
img.chroma2 {-webkit-transition: all .2s ease;}
img.chroma1 {-webkit-transition: all .1s ease;}

img.chroma9.linear {-webkit-transition: all .9s linear;}
img.chroma8.linear {-webkit-transition: all .8s linear;}
img.chroma7.linear {-webkit-transition: all .7s linear;}
img.chroma6.linear {-webkit-transition: all .6s linear;}
img.chroma5.linear {-webkit-transition: all .5s linear;}
img.chroma4.linear {-webkit-transition: all .4s linear;}
img.chroma3.linear {-webkit-transition: all .3s linear;}
img.chroma2.linear {-webkit-transition: all .2s linear;}
img.chroma1.linear {-webkit-transition: all .1s linear;}

img.chroma9.ease {-webkit-transition: all .9s ease;}
img.chroma8.ease {-webkit-transition: all .8s ease;}
img.chroma7.ease {-webkit-transition: all .7s ease;}
img.chroma6.ease {-webkit-transition: all .6s ease;}
img.chroma5.ease {-webkit-transition: all .5s ease;}
img.chroma4.ease {-webkit-transition: all .4s ease;}
img.chroma3.ease {-webkit-transition: all .3s ease;}
img.chroma2.ease {-webkit-transition: all .2s ease;}
img.chroma1.ease {-webkit-transition: all .1s ease;}

img.chroma9.ease-in {-webkit-transition: all .9s ease-in;}
img.chroma8.ease-in {-webkit-transition: all .8s ease-in;}
img.chroma7.ease-in {-webkit-transition: all .7s ease-in;}
img.chroma6.ease-in {-webkit-transition: all .6s ease-in;}
img.chroma5.ease-in {-webkit-transition: all .5s ease-in;}
img.chroma4.ease-in {-webkit-transition: all .4s ease-in;}
img.chroma3.ease-in {-webkit-transition: all .3s ease-in;}
img.chroma2.ease-in {-webkit-transition: all .2s ease-in;}
img.chroma1.ease-in {-webkit-transition: all .1s ease-in;}

img.chroma9.ease-out {-webkit-transition: all .9s ease-out;}
img.chroma8.ease-out {-webkit-transition: all .8s ease-out;}
img.chroma7.ease-out {-webkit-transition: all .7s ease-out;}
img.chroma6.ease-out {-webkit-transition: all .6s ease-out;}
img.chroma5.ease-out {-webkit-transition: all .5s ease-out;}
img.chroma4.ease-out {-webkit-transition: all .4s ease-out;}
img.chroma3.ease-out {-webkit-transition: all .3s ease-out;}
img.chroma2.ease-out {-webkit-transition: all .2s ease-out;}
img.chroma1.ease-out {-webkit-transition: all .1s ease-out;}

img.chroma9.ease-in-out {-webkit-transition: all .9s ease-in-out;}
img.chroma8.ease-in-out {-webkit-transition: all .8s ease-in-out;}
img.chroma7.ease-in-out {-webkit-transition: all .7s ease-in-out;}
img.chroma6.ease-in-out {-webkit-transition: all .6s ease-in-out;}
img.chroma5.ease-in-out {-webkit-transition: all .5s ease-in-out;}
img.chroma4.ease-in-out {-webkit-transition: all .4s ease-in-out;}
img.chroma3.ease-in-out {-webkit-transition: all .3s ease-in-out;}
img.chroma2.ease-in-out {-webkit-transition: all .2s ease-in-out;}
img.chroma1.ease-in-out {-webkit-transition: all .1s ease-in-out;}




Download chroma.css or visit the JSFiddle Demo.