Useful

2013.12.16

Cross-Browser Grayscale image example using CSS3 + JS

In categories: Tutorials, Website development

There are a lot of examples and tutorials about how to create grayscale images using CSS , CSS3 and JS, but while developing a project for one of my clients, I found out that there is no solution that would be cross-browser compatible and would support the latest Internet Explorer 10 and 11 versions. This is the reason I came up with a solution of my own and decided to share it with you.

Update: This tutorial uses browser user agent detection which is fully functional but has been deprecated for a while so I have created another grayscale image tutorial that uses browser feature detection.

Grayscale and Internet explorer 10, 11

Grayscale filter has been natively supported by Internet Explorer since version 6, but recently Microsoft decided to remove this native CSS filter and since version 10, IE does not display grayscale images using the old technique.

This is the reason why we now have to turn to grayscale JS solution. Besides this, Microsoft has released the new IE11, which is trying to hide as a different browser. Now Internet Explorer 11 has changed its user-agent and pretends to be a Gecko or WebKit browser. This is a pretty nifty move by Microsoft in order to render new IE11 on most browsers as a Gecko browser and not like the previous versions with MSIE user-agent (we all know that there are a lot of websites that check for MSIE user-agent and bring up non-standard markup). So I had to overcome this new problem as well – checking the user-agent and firing only the SVG (Scalable Vector Graphics) grayscale JS solution that is intended for IE10+ (IE6-9 support CSS grayscale).

Grayscale on Opera and Safari

Opera and Safari browsers do not support CSS grayscale filters so these browsers must be treated separately just like IE10+. Only these browsers can be fixed using JS solution which has been kindly provided by James Padolsey

Cross-Browser Grayscale image solution

Include jQuery library

This is the content of the HTML document – a simple container with images

Firefox 3.5+, Chrome, Internet explorer 6 – 9, Microsoft Edge

These browsers will be happy to serve us with CSS grayscale filters. Simply add these CSS lines in your stylesheet

Opera 9+, Safari 4+, Internet Explorer 10+

As mentioned before, Opera and Safari browsers need to grayscale solution that uses JS

That’s all about my cross-browser grayscale image solution setup. You can check out the demo or download the source. For those of you who want to get into more details, I have explained the magic behind the functions.js file, so that you could tweak the code as you need.

Tested and should work on:

  • Firefox 3.5+
  • Chrome, Safari 4+
  • Opera 9+
  • Internet Explorer 7, 8, 9, 10 and 11 (IE11)
  • Microsoft Edge

View the demo or Download source

Update: This tutorial uses browser user agent detection which is fully functional but has been deprecated for a while so I have created another grayscale image tutorial that uses browser feature detection.

Explanation and contents of functions.js file

This function getBrowser() checks the browser user agent and after that adds corresponding class to the <body> tag – this way we can target browser with CSS or fire JS functions only on those browsers that we want (Except IE11 because of the new user-agent)

 

Since IE11 cannot be detected like this because the new user agent on IE11 is trying to hide as Mozilla, we detect IE11 with this function

After we have created a way to tell what kind of browser is used by the user, we can start to target Grayscale image solutions with JS to the browsers that need it. I will start with Opera and Safari

After this, all that is left is to deal with IE10+ browsers and these lines of JS do exactly that (using SVG JS solution)

If you have any further questions, suggestions about cross-browser grayscale image example using CSS3 + JS, feel free to write them below or contact me personally.

View the demo or Download source

Other posts

Your thoughts

Thoughts

  1. Dorajistyle

    Thank you for the excellent source.:D

  2. Asutenan

    $.browser has ben deprecated

    • Nauris Kolāts

      Thanks, I know this, but for now this solution does the work :)
      I have updated this tutorial and created another one that uses browser feature detection instead

  3. aguinaldo

    Sometimes, the js solution, does not work, when i hit refresh. It returns undefined.

    • Nauris Kolāts

      Hi!

      Maybe you should try my new grayscale image tutorial. It is a bit different because it fires the grayscale funcion on images only after all of the images have been loaded.

  4. Nick

    I try to use grayscale filter with animated caption

    like this:
    http://css-plus.com/2010/05/how-to-create-an-image-caption-with-jquery/

    or this:
    http://www.newmediacampaigns.com/blog/jcaption-a-jquery-plugin-for-simple-image-captions#demo

    but it doesnt work in ie11 (using functions.js)
    it causes the caption to show up in the grayscaled photo for a sec and then it disappears since the colored photo is in front..
    can you help me please?
    thank you

    • Nauris Kolāts

      Hello, Nick!

      If you could give me a link to your solution, it would be a lot easier to get involved and help you cope with your issue.
      It sounds like some kind of z-index or element position problem, but it is just a wild guess.

  5. Fision

    How can I change code to target juts images with specific class and not all images on site

    • Nauris Kolāts

      Hola, Simon!

      In that case you could add some kind of classes to the images that you want to apply grayscale.
      And then modify the CSS:

      And after that you will have to modify the JS as well.
      Instead of

      you will have to write

  6. Patrick

    Many thanks for your code and sources. I’m working for days already to get this kind of functionality working on my website but without success. Can you please help me out. I’ve copied all your sources to my provider and tested it but the gray images are not visible, but when I hover them the coloured images appear.
    The url is http://www.need4value.com/grayoriginal.html. Many many thanks for helping me on this.
    Best regards Patrick

    • Nauris Kolāts

      Hi, Patrick!

      I have experienced the same issues working with grayscale images.
      In order to fix this you should at first check if all the images have been loaded and fire grayscale function only after that.
      This is all the magic behind it :)

  7. Mark

    Just thinking if it would be possible to detect browsers that support canvas but not the greyscale filter instead of doing user agent gymnastics…

  8. Bhojendra

    Nope! This doesn’t work in IE. I tested your source code by downloading in IE11.

    • Nauris Kolāts

      Hello!

      This is kind of weird because I just tested it on IE11 and it works without problems.
      Maybe you have enabled compatibility mode?

  9. Adriaens Annick

    Nice solution for IE11. However, when I use it on a page with lots of images to grayscale – I’m talking > 300 images – IE 11 doesn’t respond for a while because the grayscale script is still loading. Is there a way to increase the speed of the script when we want to use it on a very large amount of images ?

    • Nauris Kolāts

      Thanks! This is true, script does have a bit of a delay until it fires.
      I guess, that if you are running this script on such a lot of images, you might want to load the images using lazyload technique and applying this Grayscale script only on those images that are newly loaded.
      One other way that I haven’t tried is asynchronous loading of Grayscale function.
      I will look into this and see if I can manage to get some improved results.

  10. Emilio

    awesome script !!! is there any way to make blur work with the same way grayscale does?

    • Nauris Kolāts

      I guess that you could create or find something that would be similar to this grayscale image solution, but I just haven’t had the need to build such a thing.

  11. la kida

    how to apply this script on background-image and on hover event? tnx :)

    • Nauris Kolāts

      Hola, Kida!

      I am affraid that this solution only will work on images.
      Background images can’t be affected with this script.

  12. Dallass_13

    BLESS YOU FROM RUSSIA, you’ve saved me. Great work! Thanks a lot.

    p.s. : for those, who said about $.browser – you can use jqmigrate or moderniz, what’s problem people?

    p.p.s: sorry for my english -___-

  13. Jiskar

    Hi, this is a wonderfully put explanation. However for a novice like me, can you explain how I implement this to my wordpress site. eg. what does “Include jQuery library” mean.

    • Nauris Kolāts

      Hi, Jiskar!

      If you are just starting off on WordPress, I guess you should look into WordPress theme customization, take a look at this example: http://www.siteground.com/tutorials/wordpress/wordpress_create_theme.htm

      So at first you should get acquainted with this and after you have learned how to customize theme, you will be able to start implementing some additional functionality, like for example show off grayscale images in WordPress.
      And as for the “Include jQuery library”, it means that you should include those 2 lines of code in your themes header.php section between the head tags.

      I hope that this helps you at least a bit :)

  14. Perlmuxxed

    Just wanted to say that Opera does support filter grayscale https://developer.mozilla.org/en-US/docs/Web/CSS/filter#Browser_compatibility

    • Nauris Kolāts

      Hello!

      Thanks for the note, but you should mention that only Opera since version 17+ supports these filters.
      The majority still uses the old Opera versions that should still be considered.

  15. Timothy Maina

    Thanks for this, time & life saver!

  16. Bruce

    Hi, I see where you mentioned if you only want to target certain images to change to a class in the CSS and JS instead of using img. How many places does this need to be done? I tried replacing in the CSS and in the JS $(‘.MyClass’).each(function(),

    but all my images on the page are turning grayscale, and I only want certain ones to be.

    Any suggestions?

    • Nauris Kolāts

      Hello Bruce!

      Firstly you should make adjustments in the CSS part and replace the img tag with a class:

      And after that you should make adjustments to the functions.js file.
      For Opera and Safari:

      And then comes the IE10+:

      Should be all that is needed. Hope this helps.

  17. Bruce

    Thanks for the assistance Nauris. Everything looks great in Chrome, but in FF, the image area is blank until you hover over it, at which time a colored image appears. Is the SVG file what makes this work in FF? I may need to check the path to that, but I think it is correct. Also in IE I get colored images only? How can I troubleshoot? thxs!

    • Nauris Kolāts

      Hello!

      Yes, for Firefox it is the svg solution in CSS that makes images grayscale.
      I have experienced problems with images not being loaded on IE and Opera because the script fires prior the images have been loaded, but I guess never in Firefox. It should not have any kind of problems whatsoever because the svg solution should be stable.

      In order to troubleshoot your script you could try to change the CSS behavior. By default load all the images without grayscale and only on hover make the images grayscale. That way you at least will tell if the grayscale solution works and the path is correct. Ouh and by the way I dont know if you use it or dont, but in order to debug code I am using Firebug plugin.

  18. Bruce

    Hi, Getting closer. Seems to work in Chrome, FF, and IE 9 and below now. Not sure what is going on with IE10 and IE11, but your demo works for IE10,11 so I know it’s good!

    • Nauris Kolāts

      Hi!

      Good to hear that you managed to get it working. For IE10+ there is this script that checks if the browser is IE and if the version iz 10 or 11. Maybe you should look into that and try to test what it outputs and does it determines that the browser is IE10 or IE11.

      Check the code because if it determines that it is greater than Internet Explorer 10, it will add this class to the body:

      And from then you will tell if you can move further and look into the next part of the code and see if there are some classes that might be wrong or maybe something else.

  19. Bruce

    thanks for the hint. I checked the source in IE11 and the class is not being added to the body. but I don’t know why. I am using Drupal, so maybe there is a conflict with some other code being used in the theme.

  20. Bruce

    I figured out the problem, it had to do with the way JS closures work in Drupal. Thanks again for the code!

  21. Bruce

    Hi, one more question or idea. Does this only work in the css and js. for img or a class of img? I ask because I have a div with a class of item wrapped around the image and a paragraph tag below the image with a specific class. The paragraph is being hidden and fades in on hover of the item div using JQuery. It would be a nice effect if hovering over the item div triggered both effects at the same time. Right now they are independent.

    • Nauris Kolāts

      Hello!

      Well the SVG part of the code that will work like you mention and can be triggered via div tag. But to get it working on IE10+, Safari and opera, you will have to come up with some extra code, it seems that it won’t work like that.

  22. Bruce Gilbert

    ok, one more hopefully not too irritating question. Any ideas on getting this to work on mobile so that the image changed on touch?

    • Nauris Kolāts

      Hello, Bruce!

      I guess it should be doable, but haven’t tried such a trick :)

  23. Christian

    Hi Nauris
    i realized, that the script does not work with an later jQuery version?
    The Contao-CMS i used, takes the version 1.11.0 from here http://code.jquery.com/ and with this it does not work in IE 10+. When i change it to your version 1.8.3 then it works but then a lot other stuff of the CMS go’s wrong.
    I saw, that you use in your v2 Version the same jQuery Library. Is it possible to change the code in an easy way?
    thanks for your help

    • Nauris Kolāts

      Hi!

      Have you tried adding this jQuery Migrate library?
      It should allow you to use both the new 2.x Jquery version and the old 1.x Jquery

  24. Miroslaw

    The solution does not work in IE10-11 if there are images from other domains on page:

    • Nauris Kolāts

      Hello, Miroslaw
      I have never had the need to test it like that.
      Maybe you can give me the link to your website?

  25. Jordan

    Hi,
    thanks for this. But do you have to include jQuery UI?

    • Nauris Kolāts

      Hello, Jordan,
      You are corect, this Jquery UI is not needed here. thanks for the notice.
      I have updated the code.

  26. ulaganathan

    Its amazing.. cool post. How can i give to multiple class

    • Nauris Kolāts

      Hello,

      If you want the grayscale effect to be applied to multiple classes, then you can try replacing the existing line in the javascript code:

      with something like this:

  27. FS4000

    Hi there! Works great, but in safari (8.0.2) with columns ( -webkit-column-count ) seems to be some problems. only the first column is grayscalin’ the images, the other columns are getting ignored.

    any idea?

    • Nauris Kolāts

      Hi!

      Is that happeining on an Apple computer?
      And I am not really sure if I understand about which columns are you talking about, since the code does not have columns.

  28. Sameer Ahire

    Thanks Nauris ,
    I tried this solution.
    In my case, User can change the images what he has uploaded.
    But this soln. does not allow user to remove images which are gray scaled. As the img tag created, has the src={encrypted code} which does not allow me to change once images are Grayed out

    • Nauris Kolāts

      Hello!

      I am not quite sure what you have in mind, but this solution can be used if you would like to change the images for example some Content Management System (e.g. WordPress)

  29. Sameer

    Hi Nauris,
    Thanks for the script…
    I tried testing the script on IE 11 with win8.
    The functions.js throws an Error at line = indexsizeerror

    var imgPixels = ctx.getImageData(0, 0, canvas.width, canvas.height);

    • Nauris Kolāts

      Hello,

      I have tested it on Win8 with Internet Explorer 11, no such errors whatsoever for me.
      + It shows grayscale images and everything works splendid so I do not see that this is an issue

  30. Sameer

    Hi Nauris,

    I am trying to upload images using “jquery.uploadify-3.1.min.js”. While doing a browse and upload for images, the script throws an exception at line

    var imgPixels = ctx.getImageData(0, 0, canvas.width, canvas.height);

    with canvas.width & canvas.height going 0 (zero).

    Secondly, there is problem when I try to upload images with more than 4 MB size as it takes time to generate the URL.

    Your script is really helpful, but I am facing these few issues. Can you plz help in resolving them.

    • Nauris Kolāts

      Hi, Sameer, it might be that you have run into trouble with some other JS plugins that you are using on your project. Or the other possible reason is that you are trying to make images grayscale on the fly – you might want to try to setup and fire Grayscale functions on the image strictly after it has been uploaded, if you will try to do that simultaneously, you might run into such problems, meaning that JS script does not receive actual data about image height and width.

      And I wouldn’t suggest you to upload 4MB image files, that is way too much than we usually need since the page load times will be depressing.
      Hope that this helps.

  31. John Ortmann

    Can you update to work with latest 2.1.3 version of Jquery? not supported with any later version than 1.8.3 of jquery.

    • Nauris Kolāts

      Hello John,

      Changing Jquery version will definitely take some effort in order to test the grayscale functionality across multiple browsers and devices. I can’t promise you anything right away since I am currently doing work on some other projects.

  32. Channabasappa

    Hi Sir,
    First i want to tell great thanks for you sharing this one,it helps me a lot but
    im getting IndexSizeError in IE 10 and IE11,
    please help me, i am new to this type of error

    • Nauris Kolāts

      Hi,

      This is not the first comment of Internet Explorer error, but it doesn’t affect the grayscale functionality so I see no real reason to start debugging this weird browser.
      To be honest, I don’t see any reason why anybody would need to use this prehistoric browser with bad reputation.

      For me – if it works on Internet Explorer, then it is enough for me. I am not trying to fix every JS error that it thinks is an error (:

  33. Shishta Pradhan

    Hello Sir I’ve been working on this but there’s a n error on IE10 onwards as img_wrapper which wraps the img on IE 10 & IE 11 takes width and height way more than the img original width and height.
    Please help us through this problem

    • Nauris Kolāts

      Hi, I am affraid that currently I will not be able to deal with this issue since this was only a side project and my hands are full of work.
      But thank you for the information, if I will have time, I will look into this issue.

  34. Nauris Kolāts

    Hello guys, I have just added support for Microsoft Edge browsers. Since Microsoft Edge supports CSS filters we don’t have to use JS or svg grayscale solutions. And by the way, please note that currently Microsoft Edge comes with disabled CSS filters, you have to enable them at first to use them.

  35. Meher

    Hi Nauris,

    Thanks for the amazing tutorial.

    The demo link works in all Browser except Microsoft Edge. I am testing on my windows 10 laptop?

    Any ideas what may the reason why it is not working in Microsoft Edge.

    Thanks and Regards,

    Meher Bala

    • Nauris Kolāts

      Hi Meher,

      Thanks for the kudos :)
      If you are on Microsoft Edge, you will have to first enable CSS Filters which by default are disabled (do not ask me why) :)

      Enter in the address bar this about:flags

  36. Srinivasan

    It’s working fine for img tag. How to archive this with css background image?

    • Nauris Kolāts

      Hello, I am afraid that this tutorial is not for background images.

  37. Alex

    jQuery has removed $.browser from 1.9 and their latest release. And this solution does not work with the current versions of jQuery

  38. ifthiqur

    Great job..
    Thank you. Still I am facing a problem.
    I want to apply cross-browser greyscale in div tags. can you help me. I tried different ways. But its not working in internet explorer.
    hope you can help me..

 

Latest work