I shipped a button whose label was invisible. Same colour as its own background — 1:1 contrast, no readable text at all. It was only broken in dark mode, and my CI was green the entire time.
It was green for two reasons. I expected the first one. The second one is why I am writing this.
Reason one: the headless browser boots in light mode
axe evaluates the colour scheme that is actually rendered. It has no way to reason about a palette that was never painted. My pipeline loaded the page once, in whatever state Chromium starts in, and that state is prefers-color-scheme: light.
That part is well known, and the fix is one line:






