Un composant de fiche produit s’adapte à la largeur de son conteneur, pas à celle de l’écran : dans une colonne étroite d’une grille à trois colonnes, le bouton « Ajouter au panier » se réduit à une simple icône de panier pour ne pas déborder ; dans une colonne large, le texte complet reste affiché. Les container queries, disponibles dans les moteurs de rendu principaux depuis 2022, permettent précisément ce genre d’adaptation fine, indépendante de la taille de la fenêtre du navigateur.
Le mécanisme technique est élégant : on déclare un conteneur avec container-type: inline-size, puis on écrit une règle qui réagit à sa largeur réelle, quel que soit l’endroit où ce conteneur est placé dans la mise en page globale. C’est justement cette élégance qui masque un problème d’accessibilité fréquent, car la requête de conteneur agit sur l’apparence visuelle sans toucher automatiquement à la sémantique exposée aux technologies d’assistance.
Le code qui pose problème
.carte-produit {
container-type: inline-size;
container-name: carte;
}
@container carte (max-width: 220px) {
.bouton-panier .texte {
display: none;
}
}
Ce fragment masque visuellement le texte « Ajouter au panier » dès que le conteneur descend sous 220 pixels de large, ne laissant que l’icône. Le bouton conserve son marquage HTML d’origine :
<button class="bouton-panier">
<svg aria-hidden="true">...</svg>
<span class="texte">Ajouter au panier</span>
</button>
Ce qui casse réellement

La propriété display: none retire l’élément du rendu visuel mais aussi de l’arbre d’accessibilité : un nœud avec display: none n’est pas exposé aux technologies d’assistance, contrairement à des techniques de masquage visuel réservées à la classe .screen-reader-text ou équivalent, qui conservent le texte accessible tout en le retirant visuellement. Autrement dit, dans le conteneur étroit, le bouton perd entièrement son nom accessible textuel : il ne reste que l’icône SVG, explicitement marquée aria-hidden="true" pour éviter qu’un lecteur d’écran ne tente de la décrire par un chemin de tracé illisible.
Le résultat net : dans la colonne étroite, un lecteur d’écran annonce simplement « bouton », sans aucune indication sur son action. Le critère WCAG 4.1.2 « Nom, rôle, valeur » exige qu’un composant d’interface expose un nom accessible correspondant à sa fonction ; ici, ce nom disparaît précisément dans le cas de figure où l’espace visuel manquait déjà le plus, ce qui est aussi la situation la plus fréquente sur mobile.
Pourquoi ce piège se répète avec les container queries
- Le raisonnement responsive se concentre sur l’espace disponible, rarement sur l’arbre d’accessibilité résultant
- Le composant fonctionne visuellement dans les deux configurations, ce qui rassure à tort en recette visuelle
- Les outils d’audit automatisés testent souvent une seule taille de viewport et ne détectent pas la régression qui n’apparaît que dans un conteneur réduit
- La bascule via container query est plus difficile à repérer en revue de code qu’une media query globale, car elle dépend du contexte d’insertion du composant, pas de la fenêtre
La correction : ne jamais retirer le texte, le masquer visuellement
La correction consiste à distinguer clairement masquage visuel et suppression du contenu. Pour ce cas, une classe de masquage visuel classique, qui conserve le texte dans l’arbre d’accessibilité, résout le problème :
@container carte (max-width: 220px) {
.bouton-panier .texte {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip-path: inset(50%);
white-space: nowrap;
}
}
Le texte « Ajouter au panier » redevient invisible à l’écran mais reste présent dans le nom accessible du bouton, quelle que soit la largeur du conteneur. Le critère 4.1.2 est alors respecté dans toutes les configurations, sans sacrifier la densité visuelle recherchée dans les colonnes étroites.
Sur nos projets de grille de produits, nous testons systématiquement chaque composant responsive dans sa configuration la plus contrainte avec un lecteur d’écran actif, pas seulement dans la largeur de viewport la plus courante.
En résumé
Les container queries n’ont, en elles-mêmes, rien d’inaccessible : elles déplacent simplement le point de bascule d’un raisonnement de fenêtre à un raisonnement de conteneur. Le risque vient de la technique CSS choisie pour réagir à cette bascule. Utiliser display: none pour gagner de la place retire silencieusement un nom accessible ; une technique de masquage visuel dédiée préserve ce nom dans toutes les largeurs de conteneur. La distinction tient en une poignée de propriétés CSS, mais son absence se paie directement sur l’usage réel au lecteur d’écran.