Les trois niveaux et leur utilité réelle
La convention est quasi universelle, ce qui rend facile l'adoption de la structure sans en comprendre la logique. Chaque niveau répond à une question différente, et savoir laquelle permet d'éviter de placer les éléments au mauvais endroit.
| Réponses | Exemple | Utilisé par | |
|---|---|---|---|
| Primitive | Quelles valeurs existent dans ce design ? | blue-600, space-4, radius-md | Le niveau sémantique uniquement. Jamais le code produit |
| Sémantique | À quoi sert cette valeur ? | --color-danger, --text-muted, --surface-raised | Code produit. C'est la couche sur laquelle les développeurs s'appuient |
| Composant | Où un composant diffère-t-il légitimement ? | --button-primary-bg, --tooltip-surface | Ce composant uniquement, et rarement |
La règle qui permet au système de fonctionner, et celle qui est la plus souvent transgressée : rien en dehors du niveau sémantique ne peut référencer une primitive. Dès qu'un composant utilise blue-600 directement, le niveau primitive devient une API publique et vous ne pouvez plus modifier une valeur sans auditer l'ensemble de la base de code, ce qui était précisément la raison d'être des niveaux.
:root {
/* Tier 1: primitives. Values only. Nobody uses these directly. */
--blue-600: #2563eb;
--red-600: #dc2626;
--gray-500: #6b7280;
/* Tier 2: semantic. Roles. This is the public API. */
--color-primary: var(--blue-600);
--color-danger: var(--red-600);
--text-muted: var(--gray-500);
/* Tier 3: component. Only where a component truly deviates. */
--button-danger-bg: var(--color-danger);
}
/* ✅ product code */
.alert { color: var(--color-danger); }
/* ❌ reaches past the semantic layer */
.alert { color: var(--red-600); }Le modèle de nommage
Lecture de gauche à droite, du général au spécifique : catégorie, rôle, variante, état. Tous les tokens n'ont pas besoin de ces quatre éléments, et ceux qui en ont sont généralement interactifs.
| Catégorie | Rôle | Variante | État | |
|---|---|---|---|---|
color-text-primary | color | text | primary | — |
color-surface-raised | color | surface | raised | — |
color-action-primary-hover | color | action | primary | hover |
space-inset-lg | space | inset | lg | — |
border-subtle | border | — | subtle | — |
La cohérence importe bien plus que le modèle choisi. Une base de code où la moitié des tokens s'appellent text-color-muted et l'autre moitié color-text-muted oblige tout le monde à vérifier la syntaxe à chaque fois, indéfiniment. Choisissez un ordre, documentez-le et imposez-le lors des revues.
Un avantage pratique de l'ordre allant du général au spécifique : vos tokens se trient alphabétiquement en groupes cohérents. Tous les tokens color-surface-* sont regroupés dans l'autocomplétion de l'éditeur, transformant ainsi la convention de nommage en mécanisme de découverte.
Voici le modèle appliqué plutôt que décrit. Lisez les noms de rôles, pas les couleurs. La question à laquelle chacun doit répondre est « à quoi cela sert-il ? » ; un nom qui répond seulement à « de quelle couleur est-ce ? » a échoué par rapport au niveau auquel il se situe.
Le test pour détecter un mauvais nom
Une seule question permet de trancher la plupart des débats de nommage en quelques secondes :
Si le design changeait, ce nom serait-il toujours exact ?
Appliquez ce test à des cas réels et les réponses sont sans ambiguïté :
| Survit ? | Pourquoi | |
|---|---|---|
--color-brand-blue | Non | Passez au vert et le nom devient un mensonge que personne n'ose corriger |
--color-primary | Oui | Le rôle ne change pas lorsque la teinte change |
--text-small-gray | Non | Deux faits d'apparence, dont les deux sont susceptibles d'évoluer |
--text-muted | Oui | Nomme l'intention : un texte dont l'importance est réduite |
--shadow-card | Non | Encode le mécanisme. Passez à une élévation par trait fin et le nom devient erroné |
--elevation-raised | Oui | Nomme l'effet. Il peut s'agir d'une ombre, d'une bordure ou d'un décalage de surface |
Le cas de --shadow-card est subtil et mérite qu'on s'y attarde. Nommer un token d'après son implémentation fige cette implémentation. Une fois que chaque carte dans la base de code utilise box-shadow: var(--shadow-card), passer à une élévation basée sur des bordures devient un refactoring plutôt qu'un simple changement de token, ce qui est précisément le couplage que les tokens étaient censés supprimer.
C'est avec le mode sombre que les noms basés sur l'apparence meurent publiquement. --gray-100 en tant que « fond clair » est correct dans un thème et inversé dans l'autre ; on se retrouve donc avec un --gray-100 contenant une valeur presque noire et des utilisateurs confus. --surface-base reste vrai dans les deux cas.
Pourquoi le niveau des composants ne cesse de croître
La plupart des systèmes de tokens qui échouent le font ici. Le niveau des composants commence modestement et légitimement, puis absorbe tout, jusqu'à ce que vous vous retrouviez avec quatre cents tokens dont la moitié n'a qu'un seul utilisateur.
Le mécanisme est toujours le même. Quelqu'un a besoin d'un fond de bouton qui n'est pas tout à fait --color-primary. Ajouter --button-primary-bg prend trente secondes, alors que l'ajouter au niveau sémantique nécessite une discussion. Le token de composant est donc créé, la personne suivante fait de même, et le niveau sémantique cesse d'être la source de vérité sans que personne ne l'ait décidé.
| Le vrai problème | |
|---|---|
| Plusieurs composants ont besoin de la même valeur hors-sémantique | Un token sémantique manquant. Nommez le rôle et faites-le monter en grade |
| Un composant a besoin d'une valeur réellement unique | Légitime. C'est précisément l'utilité de ce niveau. Cela doit rester rare |
| Une surface entière nécessite des valeurs différentes | Il manque un thème ou un scope, et non des tokens de composants. Regardez ce que Encore a fait avec les layers |
| Personne ne sait quel token sémantique utiliser | Le niveau sémantique est sous-spécifié ou mal nommé |
Un audit utile : comptez les tokens de niveau composant qui n'ont qu'un seul utilisateur. Si ce nombre est élevé, le niveau est utilisé comme une solution de secours, et la correction doit se faire en amont.
Cinq erreurs et leur coût respectif
Ces erreurs reviennent dans presque tous les systèmes de tokens qui finissent par être abandonnés. Chacune a une correction simple si elle est détectée tôt, et coûteuse dans le cas contraire.
- 1
Échelles numérotées sans point d'ancrage
De
color-1àcolor-12ne signifie rien pour personne, et les chiffres n'acquièrent un sens que par folklore. Les échelles numérotées sont acceptables dans le niveau primitif, où le chiffre suit une dimension réelle comme la luminosité. Elles ne sont jamais acceptables dans le niveau sémantique, car tout l'intérêt de ce niveau est d'indiquer à quoi sert l'élément. - 2
Encoder le thème dans le nom
Utiliser
--light-bget--dark-bgcomme tokens distincts signifie que chaque composant doit référencer les deux et créer une condition. Un nom, deux valeurs, basculées par le thème : c'est à cela que sert la couche de tokens. Si vous trouvezif (theme === 'dark')dans le code d'un composant, c'est que les tokens sont mal nommés./* ❌ */ --light-bg: #fff; --dark-bg: #0a0a0a; /* ✅ */ --surface-base: #fff; [data-theme="dark"] { --surface-base: #0a0a0a; } - 3
Des tailles nommées selon leur usage actuel
--text-heroconvient parfaitement jusqu'à ce que la taille « hero » apparaisse dans un tableau de prix.--text-4xlou--font-scale-7nomment l'échelon, pas le site, et survivent à la réutilisation. Nommez par position dans une échelle, pas selon le premier client. - 4
Des couleurs de statut servant également de couleurs de marque
C'est la manière la plus courante pour un système de devenir incapable d'afficher un état. Si le vert de la marque et le vert de succès sont le même token, vous ne pouvez pas modifier le style de la marque sans changer l'apparence du succès, et vous ne pouvez pas distinguer une ligne saine d'une ligne brandée. Gardez l'ensemble des statuts réservé et précisez-le dans un commentaire.
- 5
Des abréviations que seule une personne sait interpréter
--clr-bg-scndryéconomise onze caractères mais impose à chaque lecteur une étape de décodage permanente, y compris à un modèle qui doit deviner siscndrysignifie « secondary » ou s'il s'agit d'une faute de frappe. L'autocomplétion rend la longueur quasi gratuite. Écrivez les mots en entier.
Le second point mérite un audit immédiat. Utilisez grep dans vos composants pour chercher les conditionnels de thème. Chaque occurrence trouvée est un token qui aurait dû être un nom unique avec deux valeurs, et chaque occurrence est un endroit où le mode sombre divergera silencieusement du mode clair.
Des noms qui survivent à la sortie de votre codebase
Les tokens doivent être de plus en plus portables : d'un outil de design vers le CSS, dans un thème Tailwind, dans une plateforme native, dans un élément de registre shadcn, ou dans un DESIGN.md lu par un agent. Cela impose une contrainte sur les noms que la plupart des équipes ignorent jusqu'à ce que le premier export échoue.
| Portable ? | Pourquoi | |
|---|---|---|
| Points ou slashs comme séparateurs | Risqué | color.text.muted est naturel en JSON mais illégal dans une propriété personnalisée CSS. Les traits d'union survivent partout. |
| Majuscules ou casse mixte | Risqué | Certaines cibles normalisent la casse, d'autres non. L'utilisation exclusive de minuscules élimine la question. |
| Imbrication profonde | Risqué | color.semantic.text.emphasis.high devient illisible une fois aplati et personne ne le tapera deux fois. |
| Plat, minuscules, avec traits d'union | Oui | --color-text-muted fonctionne comme variable CSS, clé JSON, clé Tailwind et mot simple dans un texte. |
La règle pratique : choisissez des noms qui soient simultanément une propriété personnalisée CSS valide, une clé JSON valide et une phrase anglaise lisible. Le format plat, en minuscules et avec traits d'union satisfait ces trois conditions. De plus, les groupes imbriqués du format de token DTCG/W3C peuvent être générés à partir d'un ensemble plat bien plus facilement que l'inverse.
Un autre test de portabilité utile : pouvez-vous prononcer le nom du token à voix haute en réunion sans avoir à l'épeler ? Si deux personnes ne s'entendent pas sur la prononciation d'un token, elles ne l'utiliseront pas non plus de manière cohérente à l'écrit.
Harmoniser les noms entre le design et le code
La décision de nommage ayant le plus d'impact n'est pas le pattern. C'est de savoir si les noms dans votre outil de design sont identiques aux noms dans le code.
Le SLDS 2 de Salesforce est l'exemple publié le plus clair : sa bibliothèque Figma utilise les mêmes noms de hooks sémantiques que le CSS (leurs propres exemples sont radius-border-4 et font-scale-4), ainsi les designs correspondent un pour un au code réel. Leur objectif affiché est un vocabulaire partagé faisant le pont entre le design et le développement.
L'effet concret est la disparition pure et simple d'une catégorie de bugs de handoff. Lorsqu'un designer dit font-scale-4 et qu'un développeur tape font-scale-4, il n'y a pas d'étape de traduction et donc aucun risque de perte de sens. Comparez cela à un style Figma appelé « Heading / Large » correspondant à une variable CSS appelée --text-2xl, où chaque handoff est une recherche et chaque recherche une occasion de se tromper.
Si vous ne pouvez effectuer qu'un seul changement dans votre système de tokens, faites correspondre les noms entre les outils. Cela demande un renommage, mais supprime une taxe permanente.
Nommer lorsque l'utilisateur est un agent
Le nommage des tokens était autrefois une question d'ergonomie humaine : autocomplétion, lisibilité, onboarding. De plus en plus, le lecteur principal de votre fichier de tokens est un agent de code, ce qui change la nature des erreurs critiques.
Un humain qui ne sait pas lequel de deux gris utiliser posera la question, ou en choisira un et sera corrigé lors de la revue. Un modèle en choisira un, silencieusement, dans chaque fichier qu'il touchera, et l'incohérence s'installera plus vite que la revue ne pourra la détecter. L'ambiguïté dans le niveau sémantique est un défaut bien plus coûteux qu'auparavant.
Nous avons analysé 299 fichiers DESIGN.md publiés pour être lus par des agents et avons constaté que 86 % spécifient les couleurs par des valeurs hexadécimales brutes sans aucun rôle sémantique associé. Pas des tokens mal nommés : aucun token. Un modèle à qui l'on donne #6b7280 en lui disant qu'il fait partie de la palette l'utilisera partout où un gris moyen semble plausible : corps de texte, bordures, icônes, placeholders, états désactivés. Cinq fonctions différentes, une seule valeur, et aucun moyen de les modifier indépendamment plus tard.
| Ce que fait l'agent | |
|---|---|
Gray: #6b7280 | L'utilise indifféremment pour le corps de texte, les bordures, les icônes, les placeholders et les états désactivés |
--text-muted: #6b7280 : texte secondaire et de soutien uniquement. Les bordures utilisent --border-subtle. L'état désactivé utilise --text-disabled. | L'utilise pour le texte de support. Les autres fonctions ont leurs propres noms, ce qui permet une divergence ultérieure. |
La seconde version coûte trois lignes supplémentaires, mais elle permet d'assombrir vos bordures sans assombrir vos légendes, une modification indispensable que la première version rend impossible sans un audit complet de la base de code.
Les kits de design d'Identity Forge proposent 28 rôles de couleurs sémantiques pour les modes clair et sombre, ainsi que la typographie, l'espacement et l'élévation, le tout sérialisé dans un fichier DESIGN.md qu'un agent lit avant d'écrire quoi que ce soit. Parcourir les kits ou lire l'explication des design tokens de couleur sémantique.
Un ensemble de base
Si vous nommez un système de zéro, c'est le minimum défendable. Il est volontairement restreint. Un système que personne ne peut garder en tête finit par être ignoré.
/* Surfaces — what things sit on */
--surface-base /* the page */
--surface-raised /* cards, panels */
--surface-overlay /* modals, popovers */
--surface-sunken /* wells, inset areas */
/* Text — by emphasis, never by colour */
--text-primary
--text-secondary
--text-muted
--text-disabled
--text-on-accent /* text sitting on the accent colour */
/* Borders — by weight of presence */
--border-subtle
--border-strong
--border-focus
/* Action — the interactive colour and its states */
--action-primary
--action-primary-hover
--action-primary-active
/* Status — reserved. Nothing decorative uses these. */
--status-success
--status-warning
--status-danger
--status-infoDeux notes sur cet ensemble. Les tokens de texte sont nommés par emphase plutôt que par couleur, afin de rester cohérents en mode sombre. Les tokens de statut comportent un commentaire de réservation, car la cause la plus fréquente de rupture d'un système de statut est un designer utilisant le vert de succès comme accent décoratif, rendant impossible la distinction entre une ligne saine et une ligne de marque.
Quelle est la meilleure convention de nommage pour les design tokens?
Trois niveaux (primitive, sémantique, composant) avec des noms allant du général au spécifique : catégorie, rôle, variante, état. L'ordre spécifique importe bien moins que l'application cohérente d'un modèle, car le coût réel de l'incohérence est une recherche manuelle à chaque utilisation.
Quelle est la différence entre les tokens primitifs et sémantiques?
Une primitive nomme une valeur (blue-600) et ne dit rien sur son usage. Un token sémantique nomme une fonction (--color-primary) et pointe vers une primitive. Le code produit ne devrait utiliser que des tokens sémantiques, afin qu'un changement de valeur ne nécessite qu'une modification d'une ligne plutôt qu'un audit de la base de code.
Dois-je nommer les tokens d'après les couleurs?
Uniquement dans le niveau primitif, où nommer la valeur est l'objectif. Dans le niveau sémantique, jamais : --color-brand-blue devient un mensonge dès que vous changez d'identité visuelle, et personne ne le renomme car trop de choses en dépendent. Nommez le rôle et laissez la valeur évoluer en dessous.
Combien de design tokens un système doit-il posséder?
Moins que vous ne le pensez. Une couche sémantique d'environ 25 à 40 rôles de couleur, plus les échelles de typographie, d'espacement et d'élévation, couvre la plupart des produits. Si le nombre dépasse la centaine, vérifiez combien en ont un seul consommateur : ce chiffre vous dira si vous avez un système ou une simple liste.
Le nommage des tokens est-il plus important maintenant que l'IA écrit le code?
Oui, car le mode de défaillance a changé. Un humain incertain sur le gris à utiliser posera la question ou sera corrigé lors de la revue. Un modèle en choisira un silencieusement dans chaque fichier qu'il touche, l'ambiguïté se propageant plus vite que la revue ne peut la détecter. La solution réside dans des noms de rôles non ambigus avec des fonctions explicitées.