blog

git clone https://git.ce9e.org/blog.git

commit
3cae11aff1465d7317e82cfcc91118ac41112a7c
parent
600082203e23f686c82c00f7de55443431c5e1cd
Author
Tobias Bengfort <tobias.bengfort@posteo.de>
Date
2026-06-28 07:33
update contrast algorithm post

Diffstat

M _content/posts/2022-09-10-contrast-algorithms/index.md 15 +++++++++------

1 files changed, 9 insertions, 6 deletions


diff --git a/_content/posts/2022-09-10-contrast-algorithms/index.md b/_content/posts/2022-09-10-contrast-algorithms/index.md

@@ -2,7 +2,7 @@
    2     2 title: Debunking claims about contrast formulas
    3     3 date: 2022-09-10
    4     4 tags: [a11y, math, color]
    5    -1 description: I want to comment on the color.js documentation on contrast. It lists a bunch of contrast formulas and explains some of their properties. I believe these explanations contain some misleading statements.
   -1     5 description: I believe the color.js documentation on contrast contains some misleading statements.
    6     6 ---
    7     7 
    8     8 I want to comment on the [color.js documentation][1] on contrast. It lists a
@@ -32,7 +32,6 @@ Let's start with some fractions.
   32    32     offset of 1:
   33    33 
   34    34         (Ymax - Ymin) / Ymin
   35    -1         = Ymax / Ymin - Ymin / Ymin
   36    35         = Ymax / Ymin - 1
   37    36 
   38    37 -   **Michelson Contrast**: `(Ymax - Ymin) / (Ymax + Ymin)`
@@ -42,11 +41,14 @@ Let's start with some fractions.
   42    41     `Ymin`:
   43    42 
   44    43         (Ymax - Ymin) / (Ymax + Ymin)
   45    -1         = (Ymax + Ymax - Ymax - Ymin) / (Ymax + Ymin)
   46    44         = (2 * Ymax - (Ymax + Ymin)) / (Ymax + Ymin)
   47    45         = (Ymax - (Ymax + Ymin) / 2) / ((Ymax + Ymin) / 2)
   48    46         = (Ymax - Yavg) / Yavg
   49    47 
   -1    48     It can also easily be calculated from simple contrast:
   -1    49 
   -1    50         (Ymax / Ymin - 1) / (Ymax / Ymax + 1)
   -1    51 
   50    52 -   **WCAG 2.1**: `(Ymax + 0.05) / (Ymin + 0.05)`
   51    53 
   52    54     The authors correctly observe:
@@ -55,7 +57,7 @@ Let's start with some fractions.
   55    57     > increase to both colors to account for viewing flare
   56    58 
   57    59     In other words: This *is* simple contrast. But instead of only considering
   58    -1     the light that is produced by the color itself, it also factors in the
   -1    60     the light that is produced by the screen itself, it also factors in the
   59    61     light that is contributed by the viewing conditions.
   60    62 
   61    63 Admittedly, these formulas are not exactly the same. But I cannot see how you
@@ -81,7 +83,8 @@ In other words, two contrast formulas are equivalent if there is a strictly
   81    83 monotonic map between them. I call such a map a "scaling".
   82    84 
   83    85 For example, simple contrast and Weber contrast are equivalent according to
   84    -1 this definition because `scale(x) = x - 1` is strictly monotonic.
   -1    86 this definition because `scale(x) = x - 1` is strictly monotonic. The same goes
   -1    87 for Michelson contrast.
   85    88 
   86    89 You could also have a stricter definition and require contrast formulas to be
   87    90 perceptually uniform in the sense that a doubling in the perceived contrast
@@ -100,7 +103,7 @@ Lmin` as a way to calculate contrast:
  100   103 > greater for a dark pair of colors than a light pair), lightness difference
  101   104 > uses the CIE Lightness `L*`, which is (approximately) perceptually uniform.
  102   105 
  103    -1 Using the CIELab definition of lightness is one option, but there are others.
   -1   106 Using the CIELab model of lightness is one option, but there are others.
  104   107 For example, there is the [Weber-Fechner law][2]:
  105   108 
  106   109     L = a * log(Y) + b