use-paired-color-tokens (stylelint)
This rule requires that background and text color design tokens styling the same surface are used as the semantic pair they were designed as.
Paired tokens share a name apart from the background-color / text-color
part, so --button-background-color-primary-hover pairs with
--button-text-color-primary-hover. A pair is guaranteed to have sufficient
contrast in every theme, in dark mode and under prefers-contrast; combining
one half with an unrelated token is not, and the mismatch usually only shows up
in the theme the author did not try.
Rule Scope
The rule only reports a declaration block that sets both a background color and a text color, because a block that sets one of them takes the other from somewhere the rule cannot see: an ancestor, a sibling rule, or another pseudo-element.
Within such a block it reports two things:
Two paired tokens that are not each other’s counterpart, whether they come from different components (
--sidebar-background-colorwith--panel-text-color) or from different variants of one component (--button-background-color-menuwith--button-text-color).Two tokens of one component whose variants differ where the counterpart does not exist as a token at all, e.g.
--urlbar-box-background-color-activewith--urlbar-box-text-color-hover. Use the component’s base text color, or file a bug for the missing token.
Tokens without a counterpart make no pairing claim and are left alone. That
covers the global --background-color-* and --text-color-* tokens, which are
meant to combine freely, a component variant that deliberately has no text
color of its own and so falls back to the family’s base one, and any value that
is not a design token.
Examples of incorrect usage for this rule
.menu-item {
background-color: var(--button-background-color-menu);
color: var(--button-text-color);
}
Examples of correct usage for this rule
.menu-item {
background-color: var(--button-background-color-menu);
color: var(--button-text-color-menu);
}
.card {
background-color: var(--panel-background-color);
color: var(--text-color-deemphasized);
}
Disabling the rule
A surface that genuinely needs an unpaired combination can disable the rule for the declaration, with a comment saying why:
/* The dropdown sits on the toolbar, not on the panel it belongs to. */
/* stylelint-disable-next-line stylelint-plugin-mozilla/use-paired-color-tokens */
color: var(--toolbar-text-color);
If the pair you want does not exist, prefer filing a bug for the missing token
over disabling the rule, and reference it from a TODO.