Skip to content

Commit 055b627

Browse files
JohnMcLearclaude
andcommitted
fix(7377): compare against rendered #222/#fff, not pure black/white
First cut of textColorFromBackgroundColor computed contrast against pure black (L=0) and pure white (L=1), then returned the concrete #222/#fff the pad actually renders with. For some mid-saturation backgrounds the two comparisons disagreed — e.g. #ff0000: vs pure black = 5.25 → pick black → render #222 → actual 3.98 vs pure white = 4.00 → would-render #fff → actual 4.00 The helper picked the wrong option because it compared against the wrong target. Compare against the actual rendered colours so the returned text colour is genuinely the higher-contrast choice. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 534428d commit 055b627

1 file changed

Lines changed: 13 additions & 6 deletions

File tree

src/static/js/colorutils.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -134,16 +134,23 @@ colorutils.contrastRatio = (c1, c2) => {
134134
return (Math.max(l1, l2) + 0.05) / (Math.min(l1, l2) + 0.05);
135135
};
136136

137-
// WCAG-aware text-colour selection (issue #7377). Pick whichever of black or
138-
// white produces the higher contrast ratio against the background. For every
139-
// sRGB colour at least one of the two choices clears AA (4.5:1) — the dead
140-
// zone at the 0.5-luminosity cutoff the old implementation used is gone.
137+
// WCAG-aware text-colour selection (issue #7377). Pick whichever of the two
138+
// concrete text colours (black-ish #222 and white-ish #fff, or the equivalent
139+
// colibris CSS variables) produces the higher contrast ratio against the
140+
// background. The comparison uses the ACTUAL rendered text colours rather
141+
// than pure black/white so the result reflects what the user will see; the
142+
// old luminosity-cutoff heuristic produced sub-optimal picks for some
143+
// mid-saturation backgrounds (e.g. #ff0000 → white at 4.00:1 when #222
144+
// would have given ~3.98:1 — practically identical, and for many mid-tones
145+
// the margin is larger).
146+
const BLACK_ISH = colorutils.css2triple('#222222');
147+
const WHITE_ISH = colorutils.css2triple('#ffffff');
141148
colorutils.textColorFromBackgroundColor = (bgcolor, skinName) => {
142149
const white = skinName === 'colibris' ? 'var(--super-light-color)' : '#fff';
143150
const black = skinName === 'colibris' ? 'var(--super-dark-color)' : '#222';
144151
const triple = colorutils.css2triple(bgcolor);
145-
const ratioWithBlack = colorutils.contrastRatio(triple, [0, 0, 0]);
146-
const ratioWithWhite = colorutils.contrastRatio(triple, [1, 1, 1]);
152+
const ratioWithBlack = colorutils.contrastRatio(triple, BLACK_ISH);
153+
const ratioWithWhite = colorutils.contrastRatio(triple, WHITE_ISH);
147154
return ratioWithBlack >= ratioWithWhite ? black : white;
148155
};
149156

0 commit comments

Comments
 (0)