All Articles

Understanding Color Accessibility and Contrast

Readability of content on a website is one of the most essential things to consider when building one. How small or large is your text, is the colour contrast between the foreground and background high enough to ensure visibility? These are important as they will determine the kind of engagement your visitors or users of a software product have with it. The product may as well be rendered useless if the users cannot read the content.

Having good contrast colour on your site benefits most users but it is particularly beneficial for people with low vision( those who don’t use contrast enhancing tech), and certain types of colour blindness or colour deficiencies.


The engineering team at Names & Faces has built a component library and one of the components the designers had tasked us to build is what we call an ActionBar. An ActionBar has a background colour with foreground text on it. This component is used in a software product by various clients who get to choose a theme colour that will be applied on various components including the ActionBar.


After playing with multiple colours, one thing was evident, white colour for the text will not suffice as the only foreground colour because it is not visible enough when some colour backgrounds are applied. We were then tasked with finding an algorithm that will determine the contrast value for between the foreground text colour and the background colour which will then determine if the foreground colour should be black or white.

In this article we are going to discuss in detail the importance of contrast colour ratios and what the standard industry requirements are, as well as the algorithms used to determine contrast ratios and how they are implemented.

What is WCAG

The Web Content Accessibility Guidelines (WCAG) are the legal digital web content accessibility standards published by the World Wide Web Consortium (W3C) in partnership with various organisations and individuals to meet the needs of organisations and and governments internationally. The WCAG document was developed to outline how to create accessible web content for people with disabilities. Web Content refers to information in a web page that includes:

  • Text, image, sound, etc.
  • Code or markup that defines structure, presentation, etc.

Accessibility involves a wide range of disabilities that include speech, visual, language, auditory and neurological disabilities to name a few.

The WCAG 2 Documents

WCAG 2.0 and WCAG 2.1 are stable, reference-able technical documents that have 12 guidelines that are organised under 4 principles of accessibility.

  1. Perceivable - Users must be able to perceive information and interface component presented in a web page as well as providing text alternatives if there is video and audio content.
  2. Operable - All users must be able to use the website. The ability to operate all interface components and navigations is essential. Take for instance users with disabilities who use the keyboard to surf the web using character key shortcuts to navigate, interact with, and access content. Of most importance the site must provide the users with the option to confirm information, correct and retract on times that they make mistakes.
  3. Understandable - Make text content readable and understandable including interactive elements such as links, menus and icons which should give some insight to their destination.
  4. Robust - Content must be robust enough that it can be interpreted by a wide variety of user agents i.e different kind of devices, platforms and browsers, including assistive technologies.

Each guideline has testable success criteria which it is supposed to adhere to. They are categorised in three levels of conformance [1] based on the impact they have on design or visual presentation of the pages in order to meet the needs of different groups and different situations:

  1. A (lowest) - This is the minimum level of accessibility and it does not achieve a broad accessibility for a lot of situations.
  2. AA (mid range) - The is the most common and recommended level of conformance for all web-based information.
  3. AAA (highest) - This is the highest level of conformance and it is usually not recommended to strive for, as it is hard satisfy all Level AAA Success Criteria for some content.

Level A sets a minimum level of accessibility and does not achieve broad accessibility for many situations. AA is the most commonly recommended.

In this article we take as look into the WCAG document mainly Guideline 1.4. Distinguishable: Make it easier for users to see and hear content including separating foreground from background. Here we pull together the terms and principles needed to understand WCAG 2 requirements for contrast and colour.

Contrast and Colour

Contrast and colour use play vital pieces for accessibility, most importantly for users who are visually disabled and need to discern content on web pages. This section will briefly look into how we define colour and give a detailed understanding to how we determine the contrast ratio.

Colour Definition

We look into three ways in which colour is defined. We will use a shade of the colour yellow as an example.

  • rgb(189,183,107) - RGB stands for red, green and blue which are the primary colours. The amount of red, green and blue that form this colour are each represented by a number between 0 and 255.
  • #BDB76B - This is a hexadecimal value where the red, green and blue are presented as a combination of six letters or numbers. It is the most popular way of specifying css colours.
  • hsl(56, 38%, 58%) - HSL stands for hue, saturation, and lightness and this closely maps to how people perceive colours. If the lightness of a colour is changed, its contrast ratio to another colour also changes.

Contrast Ratio

In WCAG 2, contrast is defined as the measure of the difference in perceived brightness between two colours [2]. It can also be understood as the difference in luminance between two adjacent colours or overlaid colours (foreground / background). The brightness difference is presented as a ratio that ranges from 1 : 1 (white text on white background) to 21 : 1 (black text on a white background). Few examples are:

  • Black(#101010) - has a contrast ratio of 20.09 : 1
  • Blue (#0000FF) has a contrast ratio of 8.59 : 1
  • Grey (#808080) has a contrast ratio of 3.94 : 1

Contrast Standards A contrast ratio of 3:1 is the minimum level recommended by [[ISO-9241-3]] and [[ANSI-HFES-100-1988]] for standard text and vision. WCAG 2.0 level AA requires a contrast ratio of at least 4.5 : 1 for normal text and this ratio is used in this provision to account for the loss in contrast that results from moderately low visual acuity, congenital or acquired colour deficiencies, or the loss of contrast sensitivity that typically accompanies aging.

The rational behind this value is based on the following:

  1. The adoption of the 3:1 ratio as the acceptable minimum contrast for normal observers in the ANSI standard.
  2. Based on empirical findings from a population sample size, visual acuity of 20/40 is associated with a contrast sensitivity loss of roughly 1.5 [5]. A user with 20/40 visual acuity would thus require a contrast ratio of 3 * 1.5 = 4.5 to 1 and one with 20/80 visual acuity would require contrast of about 7:1.

The Minimum Contrast Standard is AA level requirement which reads:

The visual presentation of text and images of text has a contrast ratio of at least 4.5:1, except for the following:

  • Large Text - Large-scale text and images of large-scale text have a contrast ratio of at least 3:1.
  • Incidental - Text or images of text that are part of an inactive user interface component, that are pure decoration, that are not visible to anyone, or that are part of a picture that contains significant other visual content, have no contrast requirement.
  • LogoTypes - Text that is part of a logo or brand name has no minimum contrast requirement.

The Enhanced Contrast Standard is a AAA level requirement which reads: The visual presentation of text and images of text has a contrast ratio of at least 7:1, except for the following:

  • Large Text: Large-scale text and images of large-scale text have a contrast ratio of at least 4.5:1;
  • Incidental - Text or images of text that are part of an inactive user interface component, that are pure decoration, that are not visible to anyone, or that are part of a picture that contains significant other visual content, have no contrast requirement.

Although the higher contrast is always recommended, the algorithm we have implemented uses the AA conformance[4].

Colour Visibility Algorithm

In April 2000, the working draft for Accessibility Evaluation and Repair Tools (AERT) propose this algorithm to calculate the contrast of foreground and background colours, based on the YIQ colour space to determine the colour brightness and colour difference. w3c says “Two colours provide good colour visibility if the brightness difference and the colour difference between the two colours are greater than a set range.”

The range for colour brightness difference is 125. The range for colour difference is 500.

The formulas are presented below and the Red, Green, Blue values are from the RGB(189,183,107) format.

//pseudo code
colorBrightness = ((Red value X 299) + (Green value X 587) + (Blue value X 114)) / 1000

The code above is the pseudo code of the algorithm and the javascript implementation is presented below.

function getBrightness(color) {
  const sum = * 299 + * 587 + * 114;
  return Math.round(sum / 1000);
const brightnessDifference = (color1, color2) => {
  const brightness1 = getBrightness(color1);
  const brightness2 = getBrightness(color2);
  return Math.abs(brightness1 - brightness2);

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

The colour difference calculated from this formula is between the given theme colour(background) and white colour(foreground).

colorDifference = (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))
const colorDifference = (color1, color2) => {
  return (
    Math.max(, -
    Math.min(, +
    (Math.max(, -
      Math.min(, +
    (Math.max(, - Math.min(,

A colour brightness of over 125 and a colour difference of over 500 rendered a pass.

The reason we discarded this algorithm was because for the middle range colours, the algorithm seemed to be discarding a lot of those colors, suggesting that they do meet the AA standard as they are all below the required range. It raised high concerns that a lot of colors were being discarded. From observation it could be seen that the color contract was good enough. Examples are shown below of background colors which are suggested to not have good visibility with a white foreground.




After much research and investigation we decided to implemente the Luminosity Contrast Ratio Algorithm.

Luminosity Contrast Ratio Algorithm

This algorithm helps to determine the contrast between foreground and background colours[3]. The Red, Green, Blue values are from the RGB(189,183,107) format. The values are linearised, thus the following formula is applied to them.

const FS = 255;
const offset = 0.05;

const linearisedValue = color => {
  return parseFloat(Math.pow(color / FS, 2.2).toFixed(5));

const luminosity = color => {
  return (
    linearisedValue( * 0.2126 +
    linearisedValue( * 0.7152 +
    linearisedValue( * 0.0722

const luminosityContrastRatio = (color1, color2) => {
  const L1 = luminosity(color1);
  const L2 = luminosity(color2);

  if (L1 > L2) return (L1 + offset) / (L2 + offset);
  return (L2 + offset) / (L1 + offset);

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. The luminosity ratio is supposed to be greater than 4.5 for it to be considered a valid and acceptable colour contrast. The implemented algorithms can be accessed in codesandbox.

Not only has this investigation and implementation helped us to determine the best algorithm and minimum ratio fit for our needs, it has also exposed us to the importance of inclusivity whenever we build our products.

  5. Arditi, A. and Faye, E. (2004). Monocular and binocular letter contrast sensitivity and letter acuity in a diverse ophthalmologic practice. Supplement to Optometry and Vision Science, 81 (12S), 287.