Séparer valeurs brutes et rôles sémantiques
Un jeton primitif nomme une valeur sélectionnée ou une étape d’échelle, par exemple --color-indigo-600. Un jeton sémantique nomme un rôle d’interface, par exemple --color-action. Associer le jeton sémantique au primitif crée une seule indirection contrôlée. Les composants utilisent --color-action sans savoir si le thème le mappe à indigo, bleu ou une autre couleur validée. Cette séparation clarifie l’audit : provenance et conversions concernent les primitives, contraste et sens des états concernent les paires sémantiques. N’exposez pas toute la palette à tous les composants sans usage concret.
Sémantique ne signifie pas vocabulaire marketing subjectif. Préférez des rôles vérifiables : surface, surface-raised, text, text-muted, border, focus-ring, action, on-action, danger et on-danger. Chaque jeton de premier plan doit documenter les fonds autorisés. light-gray n’indique ni relation ni garantie d’usage ; text-muted peut avoir un contrat énumérant ses surfaces. N’inscrivez pas le thème actuel dans le nom sémantique. white-text et dark-surface compliquent un futur thème et poussent les composants à dépendre de l’apparence plutôt que de la fonction.
Comprendre cascade et héritage
Les propriétés personnalisées participent à la cascade et héritent normalement. Une déclaration sur :root est disponible pour les descendants, mais une déclaration plus proche peut la remplacer selon la cascade. Les noms sont sensibles à la casse : --color-text et --Color-text diffèrent. var() substitue la valeur calculée de la propriété à l’endroit d’utilisation. Cette puissance facilite les thèmes locaux, mais crée des dépendances cachées si les composants redéfinissent sans contrôle les noms globaux. Conservez le contrat global sur une racine ou frontière de thème documentée et préfixez les valeurs privées d’un composant.
:root {
--color-indigo-600: #4f46e5;
--color-slate-950: #020617;
--color-surface: #ffffff;
--color-text: var(--color-slate-950);
--color-action: var(--color-indigo-600);
}Garder volontairement un premier ensemble réduit
Commencez avec les rôles présents dans de vrais écrans au lieu de générer des centaines de niveaux spéculatifs. Un petit produit nécessite souvent deux ou trois surfaces, du texte principal et atténué, une bordure, une paire d’action, un indicateur de focus et quelques paires d’état. Consignez les consommateurs de chaque jeton. Sans consommateur, un jeton n’appartient peut-être pas au contrat initial. Les gammes primitives sont utiles uniquement si elles soutiennent des décisions sémantiques réelles. Un système étroit est plus facile à tester dans tous les thèmes et états.
- Paires surface et texte réellement employées dans les pages.
- Couleurs action et on-action pour les contrôles avec texte ou icône.
- Bordure et focus-ring accompagnés de preuves par état.
- Paires de statut uniquement pour les statuts communiqués par le produit.
Nommer selon le rôle et l’état
Employez une hiérarchie et un vocabulaire cohérents. Un schéma pratique est --color-<role> avec des modificateurs d’importance ou d’état, tandis que les primitives suivent --color-<hue>-<step>. La forme exacte importe moins que d’éviter primary, brand, accent et action comme synonymes du même rôle. Créez des jetons hover, active, disabled, focus ou selected seulement si l’état possède réellement une valeur distincte. Un tableau reliant jeton, fond permis, propriétaire et contraste apporte plus qu’une simple grille visuelle. Gardez le nom stable lorsque seule la valeur change.
| Couche | Exemple | Responsabilité |
|---|---|---|
| Primitive | --color-indigo-600 | Enregistrer une valeur choisie |
| Sémantique | --color-action | Décrire un rôle d’interface |
| Composant | --button-background | Adapter un rôle dans un composant |
| État | --color-action-hover | Décrire un état justifié |
Prévoir replis et thèmes
Le second argument de var() est un repli utilisé si la propriété référencée manque ou devient invalide lors de la substitution. Ce n’est pas un repli général de support navigateur, et une virgule peut faire partie de la valeur de repli. Prévoyez-le aux frontières d’intégration où un composant peut fonctionner sans thème hôte ; ne répétez pas les valeurs brutes partout. Les thèmes remplacent les associations sémantiques sur une frontière définie. Une requête média choisit une préférence par défaut, tandis qu’une classe ou un attribut représente un choix explicite avec une priorité documentée. L’exemple remplace donc ensemble la surface sombre et son texte : il forme une paire explicite au lieu de laisser un texte sombre sur un fond sombre.
.button {
color: var(--color-on-action, #ffffff);
background: var(--color-action, #4f46e5);
border: 1px solid var(--color-border, #cbd5e1);
}
@media (prefers-color-scheme: dark) {
:root {
--color-surface: #0f172a;
--color-text: #f8fafc;
}
}Tester les combinaisons, pas les échantillons
Un jeton de couleur n’est pas accessible isolément. Testez les paires premier plan et fond après composition alpha, avec hover, focus, active, disabled, selected et validation. Le focus ne doit pas être communiqué uniquement par une variation subtile de couleur. Capturer les chaînes des jetons ne démontre pas le contraste : les tests demandent les valeurs résolues et les règles de combinaison. Vérifiez forced-colors sans annuler inutilement les substitutions de l’agent utilisateur. Documentez si le jeton est décoratif, textuel ou destiné à un objet graphique, car les exigences applicables diffèrent.
- Vérifiez héritage et redéfinitions locales dans les composants imbriqués.
- Résolvez chaque combinaison premier plan et fond prise en charge.
- Testez préférence, thème explicite et comportement forced-colors.
- Auditez jetons inutilisés, dupliqués et obsolètes avant tout ajout.
Faire évoluer sans casser les consommateurs
Traitez une modification de jeton comme une modification d’API. Recherchez les consommateurs, actualisez documentation et captures, mesurez les paires touchées et fournissez un alias ou une migration lors d’un renommage public. Supprimez l’alias obsolète seulement après la migration complète. Gardez la source canonique sous contrôle de versions et ne générez d’autres formats que par un processus déterministe testé. Ne dupliquez pas la table de thème en JavaScript si CSS peut en être propriétaire. Un court journal distingue un ajustement visuel d’une rupture des hypothèses des composants.
Sources primaires
Les affirmations factuelles de cet article sont vérifiées dans ces spécifications publiées.