Ashley Sheridan​.co.uk

Testing Colour Blindness Effects Online with SVG Filters

Posted on

One of the basic rules of accessibility is to not convey information through colour alone. The WCAG lists use of colour as a Level A issue, specifically saying:

Color is not used as the only visual means of conveying information, indicating an action, prompting a response, or distinguishing a visual element.

This criterion is aimed at those people with visual disabilities, or problems that have a visual aspect. In this post, I'll show how to test your websites against the various types of colour blindness using SVG filters from within CSS as I did for my accessibility testing browser plugin.

Types of Colour Blindness

Humans percieve colours via the cones in our eyes, with 3 types (typically, although some people have 4) tuned to long, medium, and short waves, which correspond to red, green, and blue vision.

Graph showing cone sensitivity at different light wavelengths
Graph showing cone responsivity, with blue (S) peaking between 420-440nm, green (M) at 530nm, and red (L) between 534-545nm. Source: Vanessaezekowitz at en.wikipedia, CC BY-SA 3.0.

When one of these cone systems fails, the result is colour blindness. Each of the three main colour types can have a full failure to percieve the colour (dichromacy) or partial loss of perception to the colour (anomalous trichromacy).

NameRed VisionGreen VisionBlue VisionMale Population AffectedFemale Population AffectedAffect
Protanomalyanomalousnormalnormal1.3%0.02%Red not percieved as strongly as other colours
Protanopiaabsentnormalnormal1.3%0.02%Unable to see red
Deuteranomalynormalanomalousnormal5%0.35%Green not percieved as strongly as other colours
Deuteranopianormalabsentnormal1.2%0.01%Unable to see green
Tritanomalynormalnormalanomalous0.0001%0.0001%Blue not percieved as strongly as other colours
Tritanopianormalnormalabsent0.001%0.03%Unable to see blue
Achromatopsiaabsentabsentabsent0.00003%0.00003%Unable to see any colours
Jewel beetles on a leaf, repeated to show different examples of colour blindness
Jewel beetles repeated in an Andy Warhol repeated style to show from top to bottom, left to right, the normal image, and then examples of protanopia, deuteranomaly, and tritanopia. Photograph source: James Wainscoat on Unsplash

Turning This Into a CSS Filter

CSS alone isn't capable of applying the kind of colour filter that we need, but with the help of SVG and a transformation matrix it can.

What is a Transformation Matrix?

An SVG feColorMatrix element creates a matrix transform that can be applied to any HTML element, be that an image or the entire page. The matrix itself is a 5×4 which alters the various colour components of each pixel.

( r0 r1 r2 r3 r4 g0 g1 g2 g3 g4 b0 b1 b2 b3 b4 a0 a1 a2 a3 a4 )

A good introduction to colour transform matrices is the Into the Matrix with SVG Filters which explains what the values are and gives some examples.

Creating the SVG Filter

A basic feColorMatrix filter looks like this:

<filter> <feColorMatrix id="colourMatrix" type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0" /> </filter>

This particular one does nothing, as there is no subtraction or addition to any colour component. In order to actually alter the colours, we need to adjust the values for the type of colour blindness effect we want to test.

Taking protanopia as an example, which is missing red vision. The transform matrix that would achieve that is as follows:

( .56667 .43333 0 0 0 .55833 .44167 0 0 0 0 .24167 .75833 0 0 0 0 0 1 0 )

Which results in this SVG snippet:

<filter> <feColorMatrix id="protanopiaColourMatrix" type="matrix" values=".56667 .43333 0 0 0 .55833 .44167 0 0 0 0 .24167 .75833 0 0 0 0 0 1 0" /> </filter>

Applying the Filter

In my accessibility plugin, I dynamically insert the code into the body of the page I'm testing because I didn't want to have to reference external assets when all I really needed was a few lines of code. However, this need not be the case. You can reference a filter in any external SVG file. This allows you to have a file containing multiple filters if you have the need.

Then it's just a case of altering the style of any element to reference the filter:

.your-element { filter: url(#protanopiaColourMatrix); }

The result is something like this:

Jewel beetles shown through a protanopia filter which removes the red pigment

A Working Demo

And here is all of it nicely wrapped up into an interactive demo. Select one of the filters from the list of options and see the effect on the source image.

Available colour blindness filters:

Jewel beetle image used as a source for interactive colour blindness filter demo