631

Is there a simple way to display a color bitmap in grayscale with just HTML/CSS?

It doesn't need to be IE-compatible (and I imagine it won't be) -- if it works in FF3 and/or Sf3, that's good enough for me.

I know I can do it with both SVG and Canvas, but that seems like a lot of work right now.

Is there a truly lazy person's way to do this?

Michael Mullany
  • 25,795
  • 5
  • 68
  • 94
Ken
  • 6,712
  • 3
  • 16
  • 8
  • 14
    *"It doesn't need to be IE-compatible (and I imagine it won't be)"*?? IE is providing a set of [DX filters](http://bit.ly/j8TnAG) **since 1997** (IE4) which does this job with mere CSS and lot more. Now they have [dropped DX filters in IE10](http://bit.ly/rVt1aH) and are strictly following the standard SVG based filters. You might want to take a look at [this](http://bit.ly/oFcgbl) and [this demo](http://bit.ly/oSYpAe). – vulcan raven Jul 09 '12 at 00:52
  • 8
    @vulcanraven It's not really 'mere CSS' - if you disable active scripting in IE the filters stop working. – robertc Nov 04 '12 at 07:40
  • 3
    @robertc, thats about right. In contrast, if you disable javascript in any browser almost every RIA including Stackoverflow will stop working (unless the web developer have implemented the HTML-only version fallback). – vulcan raven Nov 04 '12 at 13:06
  • 2
    Just use the CSS http://stackoverflow.com/questions/286275/gray-out-image-with-css/13909292#13909292 Get my answer in this question – Sakata Gintoki Oct 18 '13 at 09:20

25 Answers25

745

Support for CSS filters has landed in Webkit. So we now have a cross-browser solution.

img {
  filter: gray; /* IE6-9 */
  -webkit-filter: grayscale(1); /* Google Chrome, Safari 6+ & Opera 15+ */
  filter: grayscale(1); /* Microsoft Edge and Firefox 35+ */
}

/* Disable grayscale on hover */
img:hover {
  -webkit-filter: grayscale(0);
  filter: none;
}
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/0/04/Wikimedia_Canadian_Community_Logo.svg/240px-Wikimedia_Canadian_Community_Logo.svg.png">

What about Internet Explorer 10?

You can use a polyfill like gray.

Hugolpz
  • 14,637
  • 24
  • 85
  • 173
Salman von Abbas
  • 21,808
  • 8
  • 64
  • 56
  • any chance we can revert this to the normal image on hover etc... I mean just apply this effect on mouseover and revert to colored image on mouseout? – foxybagga Jan 02 '12 at 07:24
  • Ah thanks but I meant we load the image as black and white but on hover we change it to normal... – foxybagga Jan 02 '12 at 19:24
  • 1
    @CamiloMartin CSS filters are only supported by Chrome 18+ – Salman von Abbas Feb 23 '12 at 14:40
  • 1
    @SalmanPK Ah... :/ well, good to know, thanks. At least Chrome's auto-update means we'll get this everywhere soon. – Camilo Martin Feb 23 '12 at 14:47
  • @michaellindahl Because CSS Filters are currently only supported by Webkit Nightlies and not any stable version of Safari. – Salman von Abbas Apr 16 '12 at 00:45
  • 2
    *Update:* Latest stable version of Google Chrome (19) now supports CSS filters. Yay! =) – Salman von Abbas May 16 '12 at 21:40
  • I can't get this to work for me at all - but I really don't know where you want that filters.svg file to be stored - Since I'm calling it from an external js script file, I stuck it in the same directory as the .js file. I get no error, when I apply the filter the whole image just disappears. – Paul Gorbas May 25 '12 at 19:21
  • 1
    @PaulGorbas `filters.svg`'s path should be relative to your html document if you are using JavaScript to add styles, so if your `filters.svg` is in yourjsdir: `yourjsdir/filters.svg` or just use an absolute url. – Salman von Abbas May 25 '12 at 20:31
  • 6
    Is there any solution for Opera? – Rustam Jul 12 '12 at 21:52
  • @Rustam No not a CSS one yet. – Salman von Abbas Jul 12 '12 at 22:59
  • @Karl Horky Rolling back the edit because Firefox upto version 9/10 has a data uri bug which prevents the filter from working. And since Chrome has silent updates and older versions have like 0 marketshare, it isn't necessary to specify a version number. – Salman von Abbas Sep 02 '12 at 23:54
  • @SalmanPK ah, I didn't catch that about earlier versions of Firefox. However, they have very low marketshare numbers too in the latest stats. I think it's probably worth it to drop support for 3.5-10 to save the HTTP request, based on requirements of course. – Karl Horky Sep 07 '12 at 21:34
  • Not support to safari v.5 and opera v.12. plz help! – Sumith Harshan Nov 06 '12 at 19:25
  • 23
    So, what's the solution for IE10? – Tom Auger Mar 27 '13 at 15:05
  • 1
    Doesn't work on Opera 12, oh our dream of being cross-browser :P – boh Jul 08 '13 at 07:49
  • @naive This will most certainly work on Opera 15 (there are no 13 or 14) because it's based on Chromium. – Salman von Abbas Jul 08 '13 at 09:09
  • @SalmanPK how can I adjust the values if let's say I want it 80% grayscale? I'm not familiar with the whole 0.333 values there. Thanks. – riseagainst Nov 08 '13 at 17:36
  • 1
    @guisasso You don't need to use the matrix type. You can use the saturate type, which I think needs no explanation. Example for 80%, `` – James van Dyke Nov 08 '13 at 19:46
  • I'm trying to get everything inside a div, regardless of what it is to be an 80% grayscale. So far I was only successful on chrome with this code -webkit-filter: grayscale(80%) brightness(100%) contrast(100%); and I can also do a transition on mouse over which is great. There is text, images, and things like a facebook like button. Everything else on IE10, opera, firefox and safaru hasn't work, but again, I'm applying it to a div. Any ideas anybody? – riseagainst Nov 11 '13 at 13:10
  • 2
    For posterity: @TomAuger, this [Q&A](http://stackoverflow.com/a/14818991/356541) has specific instructions for IE10. – Barney Sep 25 '14 at 10:32
  • for iOS, the order of your CSS matters. move ```-webkit-filter: grayscale(1);``` to the bottom, after ```filter: grayscale(1);``` – Jason R. Escamilla Aug 07 '19 at 15:41
131

Following on from brillout.com's answer, and also Roman Nurik's answer, and relaxing somewhat the the 'no SVG' requirement, you can desaturate images in Firefox using only a single SVG file and some CSS.

Your SVG file will look like this:

<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1"
     baseProfile="full"
     xmlns="http://www.w3.org/2000/svg">
    <filter id="desaturate">
        <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>

Save that as resources.svg, it can be reused from now on for any image you want to change to greyscale.

In your CSS you reference the filter using the Firefox specific filter property:

.target {
    filter: url(resources.svg#desaturate);
}

Add the MS proprietary ones too if you feel like it, apply that class to any image you want to convert to greyscale (works in Firefox >3.5, IE8).

edit: Here's a nice blog post which describes using the new CSS3 filter property in SalmanPK's answer in concert with the SVG approach described here. Using that approach you'd end up with something like:

img.desaturate{
    filter: gray; /* IE */
    -webkit-filter: grayscale(1); /* Old WebKit */
    -webkit-filter: grayscale(100%); /* New WebKit */
    filter: url(resources.svg#desaturate); /* older Firefox */
    filter: grayscale(100%); /* Current draft standard */
}

Further browser support info here.

smottt
  • 3,091
  • 11
  • 37
  • 42
robertc
  • 69,665
  • 18
  • 184
  • 170
  • 6
    In webkit you do this: `-webkit-filter: grayscale(100%);` then this: `-webkit-filter: grayscale(0);` to remove it. – SeanJA Mar 26 '12 at 23:41
  • @SeanJA Thanks for the update, WebKit started implementing this stuff [in December](http://updates.html5rocks.com/2011/12/CSS-Filter-Effects-Landing-in-WebKit) – robertc Mar 27 '12 at 00:16
  • I see it in chrome beta on both my linux laptop and my win7 machine. It didn't seem to work in chrome stable in linux (but then again, it is possible linux's version is behind windows'). – SeanJA Mar 28 '12 at 12:39
  • 1
    This method works fine for me in Chrome, but has no effect in Safari. In FF, it's making my images invisible until hover. – colmtuite Jun 07 '12 at 15:56
85

For Firefox you don't need to create a filter.svg file, you can use data URI scheme.

Taking up the css code of the first answer gives:

filter: url("data:image/svg+xml;utf8,<svg%20xmlns='http://www.w3.org/2000/svg'><filter%20id='grayscale'><feColorMatrix%20type='matrix'%20values='0.3333%200.3333%200.3333%200%200%200.3333%200.3333%200.3333%200%200%200.3333%200.3333%200.3333%200%200%200%200%200%201%200'/></filter></svg>#grayscale"); /* Firefox 3.5+ */
filter: grayscale(100%); /* Current draft standard */
-webkit-filter: grayscale(100%); /* New WebKit */
-moz-filter: grayscale(100%);
-ms-filter: grayscale(100%); 
-o-filter: grayscale(100%);
filter: gray; /* IE6+ */

Take care to replace "utf-8" string by your file encoding.

This method should be faster than the other because the browser will not need to do a second HTTP request.

mquandalle
  • 2,580
  • 18
  • 23
  • 3
    Just a note to save headaches: YUI Compressor strips spaces in data urls. So you might consider using another minifier if you want to use this solution. – Malte Feb 12 '13 at 12:13
  • 6
    @Malte Or maybe just replace spaces by a "%20" string ? – mquandalle Mar 10 '13 at 23:53
  • @mquandalle unfortunately IE10 does not support filter:gray http://blogs.msdn.com/b/ie/archive/2011/12/07/moving-to-standards-based-web-graphics-in-ie10.aspx – Jedi.za Mar 22 '13 at 11:41
  • 1
    On firefox my grey is very light. Is there any way to increase the contrast or darken it slightly? Other browsers look great. – square_eyes Nov 02 '13 at 18:12
27

Update: I made this into a full GitHub repo, including JavaScript polyfill for IE10 and IE11: https://github.com/karlhorky/gray

I originally used SalmanPK's answer, but then created the variation below to eliminate the extra HTTP request required for the SVG file. The inline SVG works in Firefox versions 10 and above, and versions lower than 10 no longer account for even 1% of the global browser market.

I have since been keeping the solution updated on this blog post, adding support for fading back to color, IE 10/11 support with SVG, and partial grayscale in the demo.

img.grayscale {
  /* Firefox 10+, Firefox on Android */
  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");

  /* IE 6-9 */
  filter: gray;

  /* Chrome 19+, Safari 6+, Safari 6+ iOS */
  -webkit-filter: grayscale(100%);
}

img.grayscale.disabled {
  filter: none;
  -webkit-filter: grayscale(0%);
}
Community
  • 1
  • 1
Karl Horky
  • 3,362
  • 27
  • 33
14

Simplest way to achieve grayscale with CSS exclusively is via the filter property.

img {
    -webkit-filter: grayscale(100%); /* Safari 6.0 - 9.0 */
    filter: grayscale(100%);
}

The property is still not fully supported and still requires the -webkit-filter property for support across all browsers.

AdamMcquiff
  • 1,974
  • 4
  • 22
  • 40
NK Chaudhary
  • 371
  • 3
  • 13
14

If you are able to use JavaScript, then this script may be what you are looking for. It works cross browser and is working fine for me so far. You can't use it with images loaded from a different domain.

http://james.padolsey.com/demos/grayscale/

chrismacp
  • 3,716
  • 1
  • 27
  • 35
12

Just got the same problem today. I've initially used SalmanPK solution but found out that effect differs between FF and other browsers. That's because conversion matrix works on lightness only not luminosity like filters in Chrome/IE . To my surprise I've found out that alternative and simpler solution in SVG also works in FF4+ and produces better results:

<svg xmlns="http://www.w3.org/2000/svg">
  <filter id="desaturate">
    <feColorMatrix type="saturate" values="0"/>
  </filter>
</svg>

With css:

img {
    filter: url(filters.svg#desaturate); /* Firefox 3.5+ */
    filter: gray; /* IE6-9 */
    -webkit-filter: grayscale(1); /* Google Chrome & Safari 6+ */
}

One more caveat is that IE10 doesn't support "filter: gray:" in standards compliant mode anymore, so needs compatibility mode switch in headers to work:

<meta http-equiv="X-UA-Compatible" content="IE=9" />
Community
  • 1
  • 1
RobertT
  • 3,526
  • 3
  • 26
  • 33
  • 2
    Seems a better, simpler solution - would be good if SalmanPK and mquandalle updated their solutions to this. Apparently the matrix they use [is broken](https://coderwall.com/p/-3f9gq)

    Here's the embedded data version: `filter: url("data:image/svg+xml;utf8,#grayscale");`
    – psdie Feb 12 '14 at 03:48
7

For people who are asking about the ignored IE10+ support in other answers, checkout this piece of CSS:

img.grayscale: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");
}

svg {
    background:url(http://4.bp.blogspot.com/-IzPWLqY4gJ0/T01CPzNb1KI/AAAAAAAACgA/_8uyj68QhFE/s400/a2cf7051-5952-4b39-aca3-4481976cb242.jpg);
}

svg image:hover {
    opacity: 0;
}

Applied on this markup:

<!DOCTYPE HTML>
<html>
<head>

    <title>Grayscaling in Internet Explorer 10+</title>

</head>
<body>

    <p>IE10 with inline SVG</p>
    <svg xmlns="http://www.w3.org/2000/svg" id="svgroot" viewBox="0 0 400 377" width="400" height="377">
      <defs>
         <filter id="filtersPicture">
           <feComposite result="inputTo_38" in="SourceGraphic" in2="SourceGraphic" operator="arithmetic" k1="0" k2="1" k3="0" k4="0" />
           <feColorMatrix id="filter_38" type="saturate" values="0" data-filterid="38" />
        </filter>
      </defs>
      <image filter="url(&quot;#filtersPicture&quot;)" x="0" y="0" width="400" height="377" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://4.bp.blogspot.com/-IzPWLqY4gJ0/T01CPzNb1KI/AAAAAAAACgA/_8uyj68QhFE/s1600/a2cf7051-5952-4b39-aca3-4481976cb242.jpg" />
    </svg>

</body>
</html>

For more demos, checkout IE testdrive's CSS3 Graphics section and this old IE blog http://blogs.msdn.com/b/ie/archive/2011/10/14/svg-filter-effects-in-ie10.aspx

Joran Den Houting
  • 3,093
  • 3
  • 18
  • 50
Annie
  • 2,790
  • 7
  • 29
  • 72
7

A new way to do this has been available for some time now on modern browsers.

background-blend-mode allows you to get some interesting effects, and one of them is grayscale conversion

The value luminosity , set on a white background, allows it. (hover to see it in gray)

.test {
  width: 300px;
  height: 200px;
    background: url("http://placekitten.com/1000/750"), white; 
    background-size: cover;
}

.test:hover {
    background-blend-mode: luminosity;
}
<div class="test"></div>

The luminosity is taken from the image, the color is taken from the background. Since it is always white, there is no color.

But it allows much more.

You can animate the effect setting 3 layers. The first one will be the image, and the second will be a white-black gradient. If you apply a multiply blend mode on this, you will get a white result as before on the white part, but the original image on the black part (multiply by white gives white, multiplying by black has no effect.)

On the white part of the gradient, you get the same effect as before. On the black part of the gradient, you are blending the image over itself, and the result is the unmodified image.

Now, all that is needed is to move the gradient to get this effect dynamic: (hover to see it in color)

div {
    width: 600px;
    height: 400px;
}

.test {
    background: url("http://placekitten.com/1000/750"), 
linear-gradient(0deg, white 33%, black 66%), url("http://placekitten.com/1000/750"); 
    background-position: 0px 0px, 0px 0%, 0px 0px;
    background-size: cover, 100% 300%, cover;
    background-blend-mode: luminosity, multiply;
    transition: all 2s;
}

.test:hover {
    background-position: 0px 0px, 0px 66%, 0px 0px;
}
<div class="test"></div>

reference

compatibility matrix

vals
  • 54,758
  • 10
  • 75
  • 124
7

In Internet Explorer use the filter property.

In webkit and Firefox there is currently no way to desatuarte an image solely with CSS. so you will need to use either canvas or SVG for a client side solution.

But I think using SVG is more elegant. check out my blog post for the SVG solution that works for both Firefox and webkit: http://webdev.brillout.com/2010/10/desaturate-image-without-javascript.html

And strictly speaking since SVG is HTML the solution is pure html+css :-)

brillout
  • 8,117
  • 9
  • 60
  • 74
  • hi brillout. I noticed that your grayscale actually fails at safari. Any followup? Thanks – swan Jan 20 '11 at 23:50
  • 1
    SVG is ***not*** HTML. It's a whole different spec. – Camilo Martin Feb 23 '12 at 19:52
  • @CamiloMartin [Here is SVG in the HTML spec](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-map-element.html#svg-0). – robertc Aug 08 '12 at 12:10
  • 1
    @robertc That link is about putting an SVG in an HTML, but here's the [SVG spec](http://www.w3.org/TR/SVG11/) and here's the [HTML spec](http://www.w3.org/TR/html/). The fact that both are similar to each other (or, to XML) doesn't mean they are the same thing... – Camilo Martin Aug 08 '12 at 19:34
  • But this doesn't affect the fact you're right about using SVG filters :) In the near future (or now already, didn't check) we'll even have SVG filters for any HTML element in stable browsers (the fact we didn't have them already speaks a lot about the separation of both formats - the blur filter in particular will rock). – Camilo Martin Aug 08 '12 at 19:41
  • @CamiloMartin No, [this is the HTML spec](http://www.whatwg.org/specs/web-apps/current-work/multipage/), the same one I linked to. HTML parsers are required to understand SVG elements. – robertc Aug 08 '12 at 20:54
  • 1
    But it links to the SVG spec in the [reference](http://www.whatwg.org/specs/web-apps/current-work/multipage/references.html#refsSVG)... It doesn't define SVG, just says that browsers should parse it. It's like Javascript or CSS in that regard. – Camilo Martin Aug 09 '12 at 21:02
7

Doesn't look like it's possible (yet), even with CSS3 or proprietary -webkit- or -moz- CSS properties.

However, I did find this post from last June that used SVG filters on HTML. Not available in any current browser (the demo hinted at a custom WebKit build), but very impressive as a proof of concept.

Roman Nurik
  • 29,417
  • 7
  • 81
  • 82
4

Maybe this way help you

img {
    -webkit-filter: grayscale(100%); /* Chrome, Safari, Opera */
    filter: grayscale(100%);
}

w3schools.org

YuZA
  • 105
  • 1
  • 2
  • 11
3

It's in fact easier to do it with IE if I remember correctly using a proprietary CSS property. Try this FILTER: Gray from http://www.ssi-developer.net/css/visual-filters.shtml

The method by Ax simply makes the image transparent and has a black background behind it. I'm sure you could argue this is grayscale.

Although you didn't want to use Javascript, I think you'll have to use it. You could also use a server side language to do it.

Community
  • 1
  • 1
alex
  • 438,662
  • 188
  • 837
  • 957
  • I do not even have a Windows box, so thanks, but that's of little use to me. – Ken Mar 04 '09 at 05:38
  • In that case, you can look at it with a Virtual Machine with IE, implement ax's method or use canvas... note that grayscaling on large images with canvas can be quite taxing on the Javascript engine. – alex Mar 04 '09 at 05:40
  • 7
    `filter: gray` is present in Internet Explorer since *Version 4*. They have taken a lot of crap for their product - rightly! - but they were really ahead of their time with this stuff – Pekka Oct 26 '10 at 19:19
2

support for native CSS filters in webkit has been added from the current version 19.0.1084.46

so -webkit-filter: grayscale(1) will work and which is easier than SVG approach for webkit...

hjindal
  • 545
  • 6
  • 16
2

Here's a mixin for LESS that will let you choose any opacity. Fill in the variables yourself for plain CSS at different percentages.

Neat hint here, it uses the saturate type for the matrix so you don't need to do anything fancy to change the percentage.

.saturate(@value:0) {
    @percent: percentage(@value);

    filter: url("data:image/svg+xml;utf8,<svg%20xmlns='http://www.w3.org/2000/svg'><filter%20id='grayscale'><feColorMatrix%20type='saturate'%20values='@value'/></filter></svg>#grayscale"); /* Firefox 3.5+ */
    filter: grayscale(@percent); /* Current draft standard */
    -webkit-filter: grayscale(@percent); /* New WebKit */
    -moz-filter: grayscale(@percent);
    -ms-filter: grayscale(@percent);
    -o-filter: grayscale(@percent);
}

Then use it:

img.desaturate {
    transition: all 0.2s linear;
    .saturate(0);
    &:hover {
        .saturate(1);
    }
}
James van Dyke
  • 4,380
  • 3
  • 24
  • 25
2

As a complement to other's answers, it's possible to desaturate an image half the way on FF without SVG's matrix's headaches:

<feColorMatrix type="saturate" values="$v" />

Where $v is between 0 and 1. It's equivalent to filter:grayscale(50%);.

Live example:

.desaturate {
    filter: url("#desaturate");
    -webkit-filter: grayscale(50%);
}
figcaption{
    background: rgba(55, 55, 136, 1);
    padding: 4px 98px 0 18px;
    color: white;
    display: inline-block;
    border-top-left-radius: 8px;
    border-top-right-radius: 100%;
    font-family: "Helvetica";
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
  <filter id="desaturate">
   <feColorMatrix type="saturate" values="0.4"/>
  </filter>
</svg>

<figure>
  <figcaption>Original</figcaption>
  <img src="http://www.placecage.com/c/500/200"/>
  </figure>
<figure>
  <figcaption>Half grayed</figcaption>
  <img class="desaturate" src="http://www.placecage.com/c/500/200"/>
</figure>

Reference on MDN

smottt
  • 3,091
  • 11
  • 37
  • 42
Bigood
  • 9,457
  • 3
  • 36
  • 65
2

You don't need use so many prefixes for full use, because if you choose prefix for old firefox, you don't need use prefix for new firefox.

So for full use, enough use this code:

img.grayscale {
    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 */
    filter: gray; /* IE6-9 */
    -webkit-filter: grayscale(100%); /* Chrome 19+, Safari 6+, Safari 6+ iOS */
}

img.grayscale.disabled {
    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");
    filter: none;
    -webkit-filter: grayscale(0%);
}
maťo
  • 1,092
  • 7
  • 14
2

If you're willing to use Javascript, then you can use a canvas to convert the image to grayscale. Since Firefox and Safari support <canvas>, it should work.

So I googled "canvas grayscale", and the first result was http://www.permadi.com/tutorial/jsCanvasGrayscale/index.html which seems to work.

Shalom Craimer
  • 18,411
  • 8
  • 66
  • 100
1

be An alternative for older browser could be to use mask produced by pseudo-elements or inline tags.

Absolute positionning hover an img (or text area wich needs no click nor selection) can closely mimic effects of color scale , via rgba() or translucide png .

It will not give one single color scale, but will shades color out of range.

test on code pen with 10 different colors via pseudo-element, last is gray . http://codepen.io/gcyrillus/pen/nqpDd (reload to switch to another image)

G-Cyrillus
  • 85,910
  • 13
  • 85
  • 110
1

Based on robertc's answer:

To get proper conversion from colored image to grayscale image instead of using matrix like this:

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

You should use conversion matrix like this:

0.299 0.299 0.299 0
0.587 0.587 0.587 0
0.112 0.112 0.112 0
0     0     0     1

This should work fine for all the types of images based on RGBA (red-green-blue-alpha) model.

For more information why you should use matrix I posted more likely that the robertc's one check following links:

Andrew Morton
  • 21,016
  • 8
  • 48
  • 69
Kajiyama
  • 3,163
  • 7
  • 23
  • 37
  • I agree 0.3333 is wrong; `0.2126 0.7152 0.0722 0 0` appears to be the equivalent of `` – Neil Aug 12 '14 at 21:13
  • The link to "The luminance and colour difference signals" is also broken. I couldn't find a replacement. – thisgeek Nov 29 '16 at 19:08
0

You can use one of the functions of jFunc - use the function "jFunc_CanvasFilterGrayscale" http://jfunc.com/jFunc-functions.aspx

Dany Maor
  • 2,223
  • 2
  • 15
  • 22
0

Try this jquery plugin. Although, this is not a pure HTML and CSS solution, but it is a lazy way to achieve what you want. You can customize your greyscale to best suit your usage. Use it as follow:

$("#myImageID").tancolor();

There's an interactive demo. You can play around with it.

Check out the documentation on the usage, it is pretty simple. docs

Nicholas TJ
  • 1,366
  • 14
  • 28
0

For grayscale as a percent in Firefox, use saturate filter instead: (search for 'saturate')

filter: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><filter id='saturate'><feColorMatrix in='SourceGraphic' type='saturate' values='0.2' /></filter></svg>#saturate"
dval
  • 352
  • 5
  • 14
0

One terrible but workable solution: render the image using a Flash object, which then gives you all the transformations possible in Flash.

If your users are using bleeding-edge browsers and if Firefox 3.5 and Safari 4 support it (I don't know that either do/will), you could adjust the CSS color-profile attribute of the image, setting it to a grayscale ICC profile URL. But that's a lot of if's!

richardtallent
  • 32,451
  • 13
  • 78
  • 116
-1

If you, or someone else facing a similar problem in future are open to PHP. (I know you said HTML/CSS, but maybe you are already using PHP in the backend) Here is a PHP solution:

I got it from the PHP GD library and added some variable to automate the process...

<?php
$img = @imagecreatefromgif("php.gif");

if ($img) $img_height = imagesy($img);
if ($img) $img_width = imagesx($img);

// Create image instances
$dest = imagecreatefromgif('php.gif');
$src = imagecreatefromgif('php.gif');

// Copy and merge - Gray = 20%
imagecopymergegray($dest, $src, 0, 0, 0, 0, $img_width, $img_height, 20);

// Output and free from memory
header('Content-Type: image/gif');
imagegif($dest);

imagedestroy($dest);
imagedestroy($src);

?>
Lyndon White
  • 24,284
  • 15
  • 77
  • 126
Trufa
  • 35,711
  • 41
  • 118
  • 180
  • 4
    @Tom, based on the votes and favorites on the original question, the OP isn't the only person who wondered if this is possible. Sure, this answer might bend the rules, but I don't see the point in downvoting an answer that might be useful to a lot of people. – Michael Martin-Smucker Oct 26 '10 at 19:37
  • 1
    @Tom, I though though it might no be an exact reply to the question,it might come in handy as it actually "solves" the problem of the grayscale without the "hassle" of javascript, maybe he didnt even consider or knew about PHP GD, no harm intended. @mlms13 that was the point exactly, thanks :) – Trufa Oct 26 '10 at 20:12
  • That's my bad , "thought" about _that other users can benefit from this post_ slipped away from my mind.. Apologies @Trufa. – tomsseisums Oct 26 '10 at 20:19
  • @Tom don´t worry about it!! I realize this answer is in the limit of relevant and this things might happen! Thanks for the apology! :) – Trufa Oct 26 '10 at 21:01
  • 3
    That did help me, put me on the right track after a few other dead ends. I found that using "imagefilter($source, IMG_FILTER_GRAYSCALE);" gave a much better result though. (PHP 5 only) – chrismacp Dec 08 '10 at 17:20
  • 5
    Voted down, since it's virtually off topic. Grayscaling an image on the server side is completely different from CSS/HTML. – Simon Steinberger Oct 02 '12 at 07:03