culori icon indicating copy to clipboard operation
culori copied to clipboard

Add support for WCAG3 contrast using APCA

Open meodai opened this issue 2 years ago • 8 comments

Would love to see this in culori to be able to play with it.

  • https://github.com/Myndex/SAPC-APCA/
  • https://github.com/Myndex/SAPC-APCA/blob/master/src/JS/SAPC_0_98G_4g_minimal.js

meodai avatar Dec 07 '22 11:12 meodai

Given APCA's license requirements around accuracy, correctness and up-to-dateness, as well as its current status as a work in progress, I don't see it as a good fit for inclusion in culori at the moment, but since culori itself is mostly a collection of functions, interoperation is fairly simple.

To obtain the Y (luminance) to pass to the contrast algorithm, you can use the wcagLuminance() function.

import { wcagLuminance } from 'culori';
import { APCAcontrast } from 'apca-w3';

const textY = wcagLuminance('black');
const backgroundY = wcagLuminance('tomato');
const contrast = APCAcontrast(textY, backgroundY);

Note that culori's wcagLuminance function is a bit different (but not fundamentally) from the equations proposed in apca-w3. You can use apca-w3's sRGBtoY() as an alternative computation that matches the exact formula.

danburzo avatar Dec 10 '22 09:12 danburzo

@danburzo thanks! I was not aware of the "non commercial" license. Such a strange decisions, especially for something like that

meodai avatar Dec 11 '22 15:12 meodai

@danburzo looks like there is a different license for the w3 version, that is more permissive: https://github.com/Myndex/apca-w3

meodai avatar Dec 11 '22 15:12 meodai

I was actually referring to the license for the w3 version :-).

To give an example, since some of the math — such as conversion between color spaces, luminance computation etc. — is already in our codebase, we would want to use that code. apca-w3 uses slightly different constants & formulas (see this w3c/silver issue), which would make our implementation non-compliant (I think!).

It really sounds like this should remain a separate library, at least until it gets merged in some form in w3 specs.

danburzo avatar Dec 11 '22 19:12 danburzo

Makes total sense. Thanks for clarifying.

meodai avatar Dec 11 '22 20:12 meodai

...since some of the math — such as conversion between color spaces, luminance computation etc. — is already in our codebase, we would want to use that code. apca-w3 uses slightly different constants & formulas.... which would make our implementation non-compliant (I think!).

Hi @danburzo and @meodai

Yes, APCA does not use the sRGB to XYZ of IEC, instead, APCA calculates "Estimated Screen Luminance" Which is intended to more correctly model a calibrated sRGB monitor. And this is important for some yet unreleased feaures that more specifically accommodate certain color vision issues.

As far as color spaces, as it is perceptual contrast, It's based around color spaces of physical monitors as opposed to theoretical spaces.

We have been talking about ways to reconcile with the "math convenience" methods, But I'm currently very swamped with other pressing matters.

IN THE MEANTIME

There is a variant that is designed to work with existing standard color maths—convert the color to $CIE\ L*$ (Lstar) and then use DeltaPhiStar (DPS contrast).

It is not polarity aware, and is a more general contrast math, But it is also much much simpler. Here's the repo:

https://github.com/Myndex/deltaphistar

Myndex avatar Jan 28 '23 06:01 Myndex

@Myndex thanks for the pointer! So that would basically be:

import { lab65 } from 'culori';

/*
  Delta Phi Star perceptual lightness contrast by Andrew Somers:
  https://github.com/Myndex/deltaphistar 
*/
const PHI = 0.5 + Math.sqrt(1.25);

function dpsContrast(a, b) {
  const dps = Math.abs(Math.pow(lab65(a).l, PHI) - Math.pow(lab65(b).l, PHI));
  const contrast = Math.pow(dps, 1/PHI) * Math.SQRT2 - 40;
  return contrast < 7.5 ? 0 : contrast;
}

danburzo avatar Jan 28 '23 07:01 danburzo

Hi @danburzo

Doh! I just saw this, but yes, that's it... Be aware there may be a change regarding DPS contrast in the next few months, mainly for tighter alignment with APCA light mode.

Myndex avatar Nov 04 '23 18:11 Myndex