@layer reset, elements, composants, utilitaires; — cette seule ligne, ajoutée en tête de feuille de style lors d’une refonte CSS, a suffi à faire disparaître un contour de focus soigneusement calibré des mois plus tôt sur les liens du menu principal. Aucune des règles concernées n’a pourtant été modifiée : seul leur ordre relatif de priorité a changé.
Ce billet diagnostique cette régression précise, provoquée par un ordre de couches CSS mal pensé lors de l’introduction des cascade layers dans la feuille de style d’un thème. Il ne traite pas de :focus-visible en tant que tel, dont le comportement reste inchangé ; le problème se situe entièrement dans l’ordonnancement des couches.
Symptôme
Le contour de focus des liens du menu principal, autrefois parfaitement visible à la tabulation, a cessé de s’afficher après une refonte qui a introduit les couches CSS pour mieux organiser la feuille de style du thème. Aucun rapport de bug n’a été ouvert immédiatement : la disparition n’a été remarquée que lors d’un test manuel au clavier, plusieurs semaines après le déploiement.
Diagnostic
La feuille de style organise désormais ses règles en quatre couches déclarées dans cet ordre :
@layer reset, elements, composants, utilitaires;
@layer elements {
a:focus-visible {
outline: 3px solid #1a56db;
outline-offset: 2px;
}
}
@layer utilitaires {
.menu-principal a {
outline: none;
}
}
La règle .menu-principal a { outline: none; } a été ajoutée dans la couche utilitaires à une autre occasion, pour neutraliser un contour indésirable sur un élément décoratif sans rapport avec le menu. Avec les couches CSS, l’ordre de priorité ne dépend plus de la spécificité des sélecteurs mais de l’ordre de déclaration des couches elles-mêmes : une couche déclarée plus tard dans la liste @layer l’emporte systématiquement sur une couche déclarée plus tôt, quelle que soit la précision du sélecteur utilisé à l’intérieur.
Ici, utilitaires est déclarée après elements. Le sélecteur a:focus-visible, pourtant plus spécifique que .menu-principal a en spécificité CSS classique, perd malgré tout la priorité, simplement parce que sa couche vient plus tôt dans l’ordre global. Le contour de focus s’efface, sans qu’aucune erreur ni avertissement n’indique la cause.

Correctif
Deux approches corrigent la situation, avec des implications différentes pour la suite du projet. La première consiste à reclasser la règle de focus dans une couche déclarée après utilitaires, en créant une couche dédiée à l’accessibilité, volontairement placée en dernière position :
@layer reset, elements, composants, utilitaires, accessibilite;
@layer accessibilite {
a:focus-visible {
outline: 3px solid #1a56db;
outline-offset: 2px;
}
}
Cette approche a l’avantage de rendre explicite l’intention : les styles de focus, jugés prioritaires par principe, vivent dans une couche dont le nom rappelle pourquoi elle passe après toutes les autres. La seconde approche, plus ponctuelle, consiste à corriger directement la règle fautive dans utilitaires, en ciblant plus précisément l’élément visé initialement plutôt que d’écraser tout contour sur les liens du menu :
@layer utilitaires {
.badge-decoratif {
outline: none;
}
}
Cette seconde correction traite la cause réelle du problème initial — un contour indésirable sur un badge décoratif — sans recourir à un sélecteur aussi large que .menu-principal a, qui n’avait jamais été la cible visée à l’origine.
Prévention
Trois pratiques ont été adoptées pour éviter que ce type de régression ne se reproduise à l’avenir sur ce projet :
- Documenter, en commentaire au-dessus de la déclaration
@layerprincipale, le rôle attendu de chaque couche et la raison de son positionnement relatif aux autres. - Réserver une couche dédiée, positionnée volontairement en dernier, pour tout style directement lié à l’accessibilité — focus visible, contrastes renforcés, tailles de police minimales — afin qu’elle ne puisse jamais être écrasée par inadvertance par une couche ajoutée plus tard sans réflexion sur l’ordre global.
- Ajouter un test visuel automatisé de non-régression sur le contour de focus des éléments interactifs principaux, déclenché à chaque modification de la feuille de style globale, plutôt que de compter uniquement sur une vérification manuelle occasionnelle.
Conseil maison : avant d’introduire les cascade layers sur un projet existant, lister d’abord les règles jugées non négociables — focus visible en tête — et leur réserver la dernière position de la liste
@layer, avant même d’y ranger le reste des styles.
En résumé
Les cascade layers apportent un vrai confort d’organisation pour une feuille de style volumineuse, mais elles introduisent un ordre de priorité qui prime sur la spécificité classique des sélecteurs, ce qui peut surprendre une équipe habituée à raisonner uniquement en spécificité. Un style de focus considéré comme acquis peut ainsi disparaître silencieusement dès qu’une nouvelle couche, mal positionnée, vient s’intercaler après la sienne dans l’ordre global.