Feature queries CSS
Les container queries demandent la largeur d’un parent. Les media queries s’intéressent au viewport. Les feature queries posent une tout autre question : ce navigateur comprend-il ce CSS ? Avec @supports, vous livrez une base fiable, puis vous débloquez une mise en page ou des sélecteurs modernes seulement là où ils fonctionnent.
Amélioration progressive, pas un pari
Une feature query est une porte de capacité. On ne jette pas les anciens styles — on garde un layout qui marche partout, puis on ajoute une couche plus riche dans @supports quand le moteur peut parser la fonctionnalité voulue (par ex. display: grid ou gap sur flex).
Forme de base de @supports
La forme courante teste une paire propriété–valeur. Si le navigateur gère cette déclaration, les règles imbriquées s’appliquent :
.card-list {
display: block;
}
.card-list .card {
margin-bottom: 1rem;
padding: 1rem;
border: 1px solid #e2e8f0;
border-radius: 0.75rem;
background: #fff;
}
@supports (display: grid) {
.card-list {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
gap: 1rem;
}
.card-list .card {
margin-bottom: 0;
}
}
Hors du bloc, les cartes s’empilent avec une simple marge. Dans @supports (display: grid), la même liste devient une grille responsive — les moteurs anciens gardent la pile ; les modernes obtiennent la grille.
Combiner les conditions : and, or, not
Vous pouvez exiger plusieurs fonctionnalités, accepter des alternatives, ou inverser un test :
@supports (display: grid) and (gap: 1rem) {
.toolbar {
display: grid;
grid-auto-flow: column;
gap: 0.75rem;
align-items: center;
}
}
@supports (display: flex) or (display: grid) {
.cluster {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
}
@supports not (display: grid) {
.card-list .card {
max-width: 36rem;
}
}
and resserre la porte (les deux doivent passer). or l’élargit. not stylise le chemin non supporté — utile pour un repli volontaire, à condition que ce repli reste lisible et complet.
Tester les sélecteurs avec selector()
Certaines fonctionnalités sont des sélecteurs, pas des propriétés. Enveloppez-les dans selector() pour que la requête demande : « peux-tu parser ce sélecteur ? »
.nav a {
color: #0f172a;
text-decoration: none;
}
@supports selector(:has(*)) {
.nav:has(a:focus-visible) {
outline: 2px solid #2563eb;
outline-offset: 4px;
}
.card:has(img) .title {
font-weight: 700;
}
}
Sans selector(), un :has() nu dans @supports n’est pas le motif fiable. Avec lui, les navigateurs sans :has() ignorent simplement les règles enrichies et gardent les styles de lien de base.
Qui pose quelle question ?
📊 Media, container, and feature queries
| Question que vous posez | Préférer | Outil typique |
|---|---|---|
| Quelle largeur a le viewport / le contexte appareil ? | Coque de page, points de rupture | @media (…) |
| Quelle largeur a ce parent autour du composant ? | Cartes dans des emplacements inégaux | @container (…) après container-type |
| Le navigateur prend-il en charge ce CSS ? | Amélioration progressive | @supports (…) / selector(…) |
Ces outils se combinent bien : media pour la page, container pour l’emplacement, @supports pour la capacité. N’utilisez pas @supports pour simuler un breakpoint, ni @media pour simuler un test de fonctionnalité.
D’abord la base, ensuite l’enrichissement
Un pattern pratique garde l’apparence partagée hors de la porte, puis améliore le layout à l’intérieur :
.feature-panel {
padding: 1.25rem;
border-radius: 0.75rem;
background: #f8fafc;
color: #0f172a;
}
.feature-panel .lead {
margin: 0 0 0.75rem;
font-size: 1.125rem;
line-height: 1.5;
}
.feature-panel .actions {
display: block;
}
.feature-panel .actions a {
display: inline-block;
margin: 0.25rem 0.5rem 0.25rem 0;
padding: 0.5rem 0.875rem;
border-radius: 0.5rem;
background: #e2e8f0;
color: inherit;
text-decoration: none;
}
@supports (display: flex) and (gap: 0.5rem) {
.feature-panel .actions {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
.feature-panel .actions a {
margin: 0;
}
}
Chaque navigateur reçoit padding, typo et liens cliquables. Flex + gap n’apparaissent que lorsque les deux sont compris — pas de trou vide si l’un manque.
Nesting et @supports ensemble
Les pièces du Modern Toolkit se combinent. Le nesting organise les sélecteurs ; @supports garde la porte de capacité :
.pricing {
padding: 1rem;
border: 1px solid #e2e8f0;
}
@supports (display: grid) {
.pricing {
display: grid;
gap: 1rem;
& .tier {
padding: 1rem;
background: #fff;
}
& .tier .price {
font-size: 1.5rem;
font-weight: 700;
}
}
}
Si le nesting lui-même n’est pas supporté, gardez un équivalent plat à l’extérieur, ou acceptez que la forme imbriquée fasse partie du chemin enrichi — même esprit d’amélioration progressive.
À vous de jouer
- Stylisez une liste en pile verticale simple, puis enveloppez une grille Grid dans
@supports (display: grid). - Exigez
gapavecandpour que l’espacement flex/grid ne s’applique pas à moitié. - Ajoutez
@supports not (display: grid)avec un replimax-widthclair — les deux chemins doivent paraître volontaires. - Verrouillez une règle
:has()avec@supports selector(:has(*)). - Résistez à mettre tout le visuel dans
@supports; laissez couleur de marque et typo dans la base.
Erreurs fréquentes
- Mettre le seul layout utilisable dans
@supportssans base — les navigateurs sans support voient une page cassée - Écrire
@supports (display)sans valeur — les feature queries exigent une paire propriété–valeur (ouselector(…)) - Utiliser
@supportslà où@mediaconvient (ou l’inverse) — capacité ≠ largeur du viewport - Tester une propriété déjà requise par la base — ne verrouillez que l’enrichissement
- Empiler des
@supportsimbriqués pour de petits gains — préférez une couche enrichie claire
Résumé
@supportsconditionne le CSS selon la capacité du navigateur (feature queries)- Testez avec
(property: value), combinez avecand/or/not, et utilisezselector()pour les sélecteurs - Gardez une base solide ; enrichissez quand le support existe
- Retenez le trio :
@media→ viewport,@container→ taille du parent,@supports→ capacité - Le Modern Toolkit s’arrête ici — module suivant : Accessibilité & clôture (
accessibility)
🧠 Testez Vos Connaissances
Testez Vos Connaissances
Mettez-vous au défi avec ce quiz interactif et voyez à quel point vous comprenez le sujet
📝 Instructions
- Lisez chaque question attentivement
- Sélectionnez la meilleure réponse pour chaque question
- Vous pouvez refaire le quiz autant de fois que vous le souhaitez
- Votre progression sera affichée en haut