Chargement...

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 :

Unlock Grid only when Grid is understood

css
.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 :

and, or, and not in feature queries

css
@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 ? »

Gate styles that need :has()

css
.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 :

Shared skin outside; enhanced layout inside

css
.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é :

Nesting inside a support block

css
.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

  1. Stylisez une liste en pile verticale simple, puis enveloppez une grille Grid dans @supports (display: grid).
  2. Exigez gap avec and pour que l’espacement flex/grid ne s’applique pas à moitié.
  3. Ajoutez @supports not (display: grid) avec un repli max-width clair — les deux chemins doivent paraître volontaires.
  4. Verrouillez une règle :has() avec @supports selector(:has(*)).
  5. 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 @supports sans base — les navigateurs sans support voient une page cassée
  • Écrire @supports (display) sans valeur — les feature queries exigent une paire propriété–valeur (ou selector(…))
  • Utiliser @supports là où @media convient (ou l’inverse) — capacité ≠ largeur du viewport
  • Tester une propriété déjà requise par la base — ne verrouillez que l’enrichissement
  • Empiler des @supports imbriqués pour de petits gains — préférez une couche enrichie claire

Résumé

  • @supports conditionne le CSS selon la capacité du navigateur (feature queries)
  • Testez avec (property: value), combinez avec and / or / not, et utilisez selector() 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

Prêt à Commencer

Testez Vos Connaissances

Mettez-vous au défi avec ce quiz interactif et voyez à quel point vous comprenez le sujet

❓
6
Questions
🎯
70%
Pour Réussir
♾️
∞
Temps
🔄
∞
Tentatives

📝 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