Guideline 1.4 of the draft version of the Web Content Accessibility Guidelines (WCAG) 2.0 requires that it is easy to distinguish foreground information from background images or sounds. The guideline suggests a luminosity contrast ratio algorithm to help determine the contrast between foreground and background colours. To help understand the algorithm, I have provided a Luminosity Contrast Ratio Analyser (Beta), along with example luminosity contrast ratios.

Author: Gez Lemon


Suggested Luminosity Contrast Ratio Algorithm

Guideline 1.4 of WCAG 2 (draft) states, make it easy to distinguish foreground information from background images or sounds. To help developers adhere to this guideline for colour contrast, there is a suggested Luminosity Constrast Ratio algorithm, developed by Gregg Vanderheiden, Dave Kelso, and Aries Arditi at the Trace R&D Center:

(L1+.05) / (L2+.05) where L is luminosity and is defined as .2126*R + .7152*G + .0722B using linearised R, G, and B values. Linearised R (for example) = (R/FS)^2.2 where FS is full scale value (255 for 8 bit color channels). L1 is the higher value (of text or background) and L2 is the lower value.

The Gamma correction and RGB constants are derived from the Standard Default Color Space for the Internet (sRGB), and the 0.05 offset is included to compensate for contrast ratios that occur when a value is at or near zero, and for ambient light effects.

Text or diagrams and their background must have a luminosity contrast ratio of at least 5:1 for level 2 conformance to guideline 1.4, and text or diagrams and their background must have a luminosity contrast ratio of at least 10:1 for level 3 conformance to guideline 1.4.

Colour Contrast Algorithms

Checkpoint 2.2 of WCAG 1.0 states, ensure that foreground and background color combinations provide sufficient contrast when viewed by someone having color deficits or when viewed on a black and white screen. In the 26th of April 2000 working draft for Accessibility Evaluation and Repair Tools (AERT), there is a suggested algorithm to calculate the contrast of foreground and background colours, based on the YIQ colour space previously used by the NTSC television standard:

Color brightness is determined by the following formula:

((Red value X 299) + (Green value X 587) + (Blue value X 114)) / 1000

Note: This algorithm is taken from a formula for converting RGB values to YIQ values. This brightness value gives a perceived brightness for a color.

Color difference is determined by the following formula:

(maximum (Red value 1, Red value 2) - minimum (Red value 1, Red value 2)) + (maximum (Green value 1, Green value 2) - minimum (Green value 1, Green value 2)) + (maximum (Blue value 1, Blue value 2) - minimum (Blue value 1, Blue value 2))

A colour brightness difference of over 125 and a colour difference of over 500 is a pass using this algorithm. In the absence of any other published algorithm to determine colour contrast, the Juicy Studio Colour Contrast Analyser uses this algorithm.

I've created a Luminosity Contrast Ratio Analyser (Beta) to allow colour combinations to be tested against the suggested luminosity contrast ratio algorithm. Compared to the results of the contrast algorithm suggested by AERT, the results yielded by the luminosity contrast ratio algorithm seem promising. To help understand the results, I've created a test suite to show the results of using the algorithm.

Luminosity Contrast Ratio Samples

Before looking at the samples used to examine the luminosity contrast ratio, it's worth considering how colours are specified in hexadecimal to show how the samples were chosen.

Colours are specified as a three-byte hexadecimal number in RGB, where the three bytes represent the intensity of red, green, and blue of the colour respectively. A single byte represents a hexadecimal number in the range 00 to FF (0 to 255 in decimal notation), which allows 256 levels of intensity (shades) of a single colour. A colour is specified by concatenating the red, green, and blue bytes together, including a leading zero for each byte should the number be less than 10 hexadecimal (16 decimal). As each colour (red, green, and blue) has a possibility of 256 shades, this scheme allows for 16,777,216 different colours (256 * 256 * 256).

To provide samples of all possible background combinations against all possible foreground combinations would require a test harness containing 16,777,216 background colours, each listing the 16,777,216 possible foreground colours in contrast. That would obviously result in an unmanageable list, so I've only included web safe colours in the samples. Web safe colours, so called because they allow for a set of 216 colours that can be displayed by 256 byte colour systems, allow for 6 levels of intensity for red, green, and blue using the values, 00, 33, 66, 99, CC, and FF. As each byte uses the same two digits, they may be specified using a shorthand notation of a single hexadecimal number. For example, #000000 may be specified as #000 using the shorthand notation.

Each byte has 6 possible values representing the level of intensity (shade), resulting in 216 different colours (6 * 6 * 6). The example luminosity contrast ratios show 216 colour combinations against a single background colour, with links to 216 different background combinations. Whilst not as complete as a test harness for every available combination, the samples illustrate 46,656 combinations across the whole spectrum, so is adequate for testing the efficiency of the algorithm. Any other colour combinations may be tested one at a time using the Luminosity Contrast Ratio Analyser (Beta).

Effectiveness of the Proposed Algorithm

From the example luminosity contrast ratios, it's clear that the results yielded by the suggested algorithm are sensible. By definition, it's more difficult to find contrasting colours for middle range values, as the secondary colour needs to be sufficiently different to provide a decent contrast. The colour contrast algorithm suggested by AERT doesn't allow any web safe colours to be used in contrast to the middle range values #666 and #999, whereas the luminosity ratio algorithm allows for 9 web-safe colours each to be used in contrast to both of these colours. The contrast of the colours that pass may not be as clear as they could be, but this is catered for by the fact that the yielded ratios pass at level 2 rather than level 3.

As well as allowing what would seem sensible combinations that would fail the colour contrast suggested by AERT, the new algorithm fails some of the more contentious colour combinations that would pass the AERT version. For example, a background colour of #f80 and a foreground colour of #00f would pass the AERT version, but fails using the luminosity contrast ratio algorithm.

All in all, the algorithm looks very promising in helping developers and designers pick suitable colour combinations.

Category: Accessibility.


  1. [luminositycontrastratioalgorithm.php#comment1]

    I heard about a podcatcher for the blind on tWiT, Gez. (Apparently, iTunes is pretty inaccessible for blind users).

    I immediately thought - from the name of the program - that it must have been designed by you ... till I got to the site!

    Evidently, you haven't copyrighted the words "lemon' and "juice". *smile*

    Posted by Damian on

  2. [luminositycontrastratioalgorithm.php#comment2]

    Very nice work Gez. But I'm worried about this hand-holding. I mean, if someone can't work out "(L1+.05) / (L2+.05) where L is luminosity and is defined as .2126*R + .7152*G + .0722B using linearised R, G, and B values. Linearised R (for example) = (R/FS)^2.2 where FS is full scale value (255 for 8 bit color channels). L1 is the higher value (of text or background) and L2 is the lower value." in their head, they've no business calling themselves a developer.

    Posted by bruce on

  3. [luminositycontrastratioalgorithm.php#comment5]

    Hi, Gez

    That looks interesting. Perhaps you make it cover all design situations by adding a couple of other ways of specifying colours: (a) RGB, as used in Window's colour dialogue box; (b) named CSS colours, as some HTML editors' colour pickers provide only the name if you select a colour which has a name. That way you'd get even more links and therefore more chances to evangelise.

    Posted by Philip Chalmers on

Comments are closed for this entry.