Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grayscale image with CSS on Safari 5.x

I am trying to show some images on a page where they should be shown in grayscale, except on mouse hover when they smoothly transition into color. I've made it work nicely on IE, Chrome and Firefox, but it doesn't work on Safari 5.x. The problem is on Safari for Mac and Safari for Windows. Here is the code I have so far:

filter: url('desaturate.svg#greyscale'); 
filter: gray;
-webkit-filter: grayscale(1);

The first line loads an external .svg filter (I don't inline it with a url("data:... rule because I want to avoid a bug in old versions of Firefox).

The second line is for IE and seems to work just as well as filter:progid:DXImageTransform.Microsoft.BasicImage(grayScale=1);.

The last line about webkit is supposed to work on Safari 6 and above, as well as Chrome.

Is there any CSS rule to show the images with grayscale on Safari 5.x? Or, if that is not possible, can someone recommend a javascript solution, preferably one that will handle the animation to and from grayscale? I would like to avoid a server-side hack with grayscale images because that will mess up my HTML and then I'll have to do some nasty browser detection to serve HTML conditionally.

thanks

Edit:

As this has turned out to be a "notable question", please don't keep posting here more answers that only work on Safari 6 and above, or answers that include an .svg file in a data url. At the time when I wrote the OP, it was important for me to support some versions of Safari and Firefox that are today considered very dated, but nevertheless that was my original question.

I am well aware that for modern browsers grayscale filtering is easily accomplished with a few lines of CSS code, but the graphics designer was using Safari 5.x and the client was using Firefox 3.x at the time I did this project. The solution that worked for me was what Giona suggested, i.e. to use Modernizr to test for css-filtering, and if it's not supported to fall back to javascript.

If I was doing the same thing today, I'd be telling both to go update their browsers!

like image 922
alexg Avatar asked Oct 02 '12 07:10

alexg


People also ask

How do you change an image to grayscale in CSS?

In CSS, filter property is used to convert an image into grayscale image. Filter property is mainly used to set the visual effect of an image. Example 1: In this example, use filter: grayscale(100%) to convert an image into grayscale.

How do I make an image black in CSS?

0% will make the image completely black. 100% (1) is default, and represents the original image. Values over 100% will provide results with more contrast.

How do I grayscale a website?

Press shift+g (or create your own key shortcut) to (de)activate grayscaling of a web page. Originally intended for web designers who might want to test the contrast of their content by changing to grayscale, but this extension can really be used by anyone who for some reason want to remove the colors of a web page.


2 Answers

As you can see on caniuse.com , CSS3 filters are supported by very few browsers at the moment.

There are many JavaScript/jQuery fallback if you Google "javascript grayscale plugin". Here are some:

  • Grayscale.js
  • jQuery GreyScale plugin
  • Hoverizr
  • Do it with canvas (tutorial)

But i've no experience with them, so i can't suggest you which one is the best.

I tried jQuery Black And White long time ago, and it gave me a lot of issues with relative/absolute positioned images, so maybe avoid it.


Including this Modernizr build into your pages, you can target browser not supporting filters via Javascript:

if(!Modernizr.css_filters){
    /* javascript fallback here */
}

or CSS:

.no-css_filters .element {
    /* css fallback here */
}

Oh, and don't forget dowebsitesneedtolookexactlythesameineverybrowser?

like image 76
Giona Avatar answered Sep 28 '22 03:09

Giona


It's really simple, actually:

  • http://www.karlhorky.com/2012/06/cross-browser-image-grayscale-with-css.html
  • http://jsfiddle.net/KDtAX/487/

I tried using the javascript fallback, but it really made no sense, and it was really slow on large images. This made a lot more sense. Note that there is a new syntax for grayscale, and I had to manually edit the resulting minified CSS from LESS.

Here's my mixin:

.filter (...) {
    -webkit-filter: @arguments;
    -moz-filter: @arguments;
    -ms-filter: @arguments;
    -o-filter: @arguments;
    filter: @arguments;
}

And my class:

.grayscale-hover, .home-image {
    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"); /* Firefox 10+, Firefox on Android see http://jsfiddle.net/KDtAX/487/*/
    .filter(grayscale(1) blur(1px));
    filter: gray; /* IE6-9 */
    -webkit-backface-visibility: hidden; /* Fix for transition flickering */
    &:hover {
        .filter(none);
        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");
    }
}

Works and tested in IE 6+, Firefox, Chrome.

like image 44
user1429980 Avatar answered Sep 28 '22 03:09

user1429980