Skip to content

xi/apca-introduction

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

88 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

The missing introduction to APCA

What is APCA?

The Accessible Perceptual Contrast Algorithm (APCA) is a new algorithm to estimate the visual contrast between two colors. It was developed to address some issues in earlier algorithms, especially for dark colors.

APCA was created by Andrew Somers (Myndex) and was at some point in the discussion for the next major version of the W3C Accessibility Guidelines (WCAG).

An interactive demo is available at https://xi.github.io/apca-introduction/tool/.

Algorithm

function sRGBtoY(srgb) {
  var r = Math.pow(srgb[0] / 255, 2.4);
  var g = Math.pow(srgb[1] / 255, 2.4);
  var b = Math.pow(srgb[2] / 255, 2.4);
  var y = 0.2126729 * r + 0.7151522 * g + 0.0721750 * b;

  if (y < 0.022) {
    y += Math.pow(0.022 - y, 1.414);
  }
  return y;
}

function contrast(fg, bg) {
  var yfg = sRGBtoY(fg);
  var ybg = sRGBtoY(bg);
  var c = 1.14;

  if (ybg > yfg) {
    c *= Math.pow(ybg, 0.56) - Math.pow(yfg, 0.57);
  } else {
    c *= Math.pow(ybg, 0.65) - Math.pow(yfg, 0.62);
  }

  if (Math.abs(c) < 0.1) {
    return 0;
  } else if (c > 0) {
    c -= 0.027;
  } else {
    c += 0.027;
  }

  return c * 100;
}

(Source)

Thresholds

The required contrast in APCA depends on font size and weight and is defined in a table:

100 200 300 400 500 600 700 800 900
12px
14px 100 100 90 75
15px 100 90 75 70
16px 90 75 70 60 60
18px 100 75 70 60 55 55 55
21px 90 70 60 55 50 50 50
24px 75 60 55 50 45 45 45
28px 100 70 55 50 45 43 43 43
32px 90 65 50 45 43 40 40 40
36px 75 60 45 43 40 38 38 38
42px 100 70 55 43 40 38 35 35 35
48px 90 60 50 40 38 35 33 33 33
60px 75 55 45 38 35 33 30 30 30
72px 60 50 40 35 33 30 30 30 30
96px 50 45 35 33 30 30 30 30 30

For body text, the thresholds are even more restrictive:

100 200 300 400 500 600 700 800 900
12px
14px 100 100 90 75
15px 100 90 75 85
16px 90 75 85 75
18px 100 75 85 75 70
21px 90 70 75 70 65
24px 75 75 70 65 60
28px 85 70 65 60 58
32px 80 65 60 58 55
36px 75 60 58 55 53
42px

Comparison to WCAG 2.x

  • WCAG 2.x produces a ratio between 1:1 and 21:1. APCA produces a value between -108 and 105.
  • Unlike WCAG 2.x, APCA reports different values when you switch foreground and background.
  • The result of APCA is negative for light text on dark background. You will usually work with the absolute value though.
  • WCAG 2.x defines three thresholds: 3:1, 4.5:1, and 7:1. In APCA, thresholds depend on other factors such as font size and weight.
  • Compared to WCAG 2.x, APCA reports drastically lower contrast for darker colors. It also reports slightly higher contrast for lighter colors.

Also see my detailed analysis.

Examples

Visual comparison of WCAG 2.x and APCA (light context) Visual comparison of WCAG 2.x and APCA (dark context)

Status

WCAG is an important standard that is a normative part of many laws all over the world. If APCA will be part of WCAG 3 it will have a huge impact. However, currently both WCAG 3 and APCA are still in early development. Neither is officially recommended by the W3C yet. Also, any mention of APCA has been removed from the WCAG 3 draft in 2023.

Evaluating a contrast algorithm is extremly difficult because contrast perception varies from person to person and also depends on the lighting conditions. Whether APCA is actually better than WCAG 2.x is therefore hard to tell. I personally could not say from the examples above which one works better for me. A rigorous scientific evaluation is not yet available (issue).

Why this document

The original author has published a lot of information on APCA. So why did I create this introduction?

For one it was born out of my personal frustration with the original documentation. Some important pieces of information (e.g. the actual algorithm) get buried under all that text.

It also contains a lot of misleading statements. For example, it claims that the WCAG 2.x algorithm is not based on human perception (which it is) and that it produces "invalid results", which the author only substantiates by anecdotal evidence. So I felt like there was room for a more balanced introduction.

Also, contributing upstream fixes is not an option because the author is hostile to a cricitcal examination of their work. You can find ample evidence of their behavior in the issue tracker of this repo.

If you want to dig deeper, I recommend to start with the original WCAG issue and the documentation README.