Last Updated: September 09, 2019
·
10.04K
· jordanscales

Checking webpages in grayscale with CSS3 filters

Choosing a color palette for your webpage can be difficult, choosing a palette to protect against vision deficiency can be even harder. With just a few added CSS rules, you can get a glimpse of your webpage in shades of black and white - links, borders, images, et al.

CSS3 filter

The new CSS3 filter rule is a powerful new feature which allows you to set various filters such as a brightness, blur, hue, saturation, and many others on all of your HTML content. For our example, we will make use of the grayscale filter.

body {
    filter: grayscale(100%);
}

And not to forget any vendor prefixes...

body {
    filter: grayscale(100%);
    -webkit-filter: grayscale(100%);
    -moz-filter: grayscale(100%);
    -o-filter: grayscale(100%);
    -ms-filter: grayscale(100%);
}

Quick Peek

Now, to load this into any HTML document dynamically, we'll need to use javascript to gain access into document.styleSheets. Using document.styleSheets[n].insertRules(CSS_RULE_STRING), we can insert any arbitrary CSS rules into an existing stylesheet.

// document.styleSheets[0] typically has protection...
document.styleSheets[1]
    .insertRule("body{filter:grayscale(100%);}",
    document.styleSheets[1].cssRules.length);

This will insert our filter rule in the second stylesheet, in the last position.

To make things watertight, let's go ahead and append this rule to all of the document's stylesheets.

for (var i in document.styleSheets)
    document.styleSheets[i]
        .insertRule("body{filter:grayscale(100%);}",
        document.styleSheets[i].cssRules.length);

A Less Error-Prone Solution

Be careful, though, since some members of document.styleSheets are either empty or protected, we need to handle any errors that come up.

for (var i in document.styleSheets)
    try {
        document.styleSheets[i]
            .insertRule("body{filter:grayscale(100%);}", 
            document.styleSheets[i].cssRules.length);
    } catch (err) {}

Now, let's make things compact. This time with all of our vendor prefixes. I'll also include a javascript: protocol in the front, so you can enter this directly in your address bar - or create a bookmarklet.

javascript:for(var i in document.styleSheets) try{document.styleSheets[i].insertRule("body{filter:grayscale(100%);-webkit-filter:grayscale(100%);-moz-filter:grayscale(100%);-o-filter:grayscale(100%);-ms-filter:grayscale(100%);}",document.styleSheets[i].cssRules.length)}catch(err){}

Results

The results are just what we expect. Now, I must stress that the grayscale this script produces does not 100% reflect vision deficiency. I have not by any means done extensive research on this topic, but this is a quick solution to see if the highlighted colors on your page are not easily discerned with a different set of eyes.

Before:

Picture

After:

Picture

Thanks for reading.
@jdan - jordanscales.com

5 Responses
Add your response

Great article. Is nice to know that CSS got finally awesome!!

over 1 year ago ·

would be great to make a bookmarklet out of that so that you can test for greyscale as you work.

over 1 year ago ·

Hi JORDAN. Nice stuff. But it would be great if you may add a live demo.

over 1 year ago ·

Can I make a Chrome extension with this?

over 1 year ago ·

@shvelo @dperrymorrow You can copy the shortened javascript code (with the javascript: protocol prefix) into an item on your bookmarks. Then just click on that :)

over 1 year ago ·