Cette fonction est expérimentale
Puisque cette fonction est toujours en développement dans certains navigateurs, veuillez consulter le tableau de compatibilité pour les préfixes à utiliser selon les navigateurs.
Il convient de noter qu'une fonctionnalité expérimentale peut voir sa syntaxe ou son comportement modifié dans le futur en fonction des évolutions de la spécification.

La pseudo-classe :is() prend comme argument une liste de sélecteur et cible les éléments qui sont sélectionnés par un des sélecteurs de cette liste. Cela permet d'écrire de « grands » sélecteurs de façon plus concise.

La plupart des navigateurs prennent encore en charge cette fonctionnalité via une ancienne pseudo-classe préfixée — :any() (anciennes versions de Chrome, Firefox et Safari) ou avec l'ancien nom :matches(). La version :any() fonctionne comme :matches() et :is() mais nécessite l'utilisation de préfixes navigateur et elle ne prend pas en charge les sélecteurs complexes.

Note : :matches() a été renommé en is() d'après l'issue 3258 du CSSWG.

/* Sélectionne n'importe quel paragraphe au sein
   d'un header, d'un main ou d'un pied de page 
   et qui est survolé */
:is(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}

/* La notation précédente serait équivalente à */
header p:hover,
main p:hover,
footer p:hover {
  color: red;
  cursor: pointer;
}


/* La version rétro-compatible avec :-*-any()  */
:-moz-any(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}
:-webkit-any(header, main, footer) p:hover{
  color: red;
  cursor: pointer;
}
:matches(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}

Syntaxe

:is( <complex-selector-list> )


<complex-selector-list> = <complex-selector>#


<complex-selector> = <compound-selector> [ <combinator>? <compound-selector> ]*


<compound-selector> = [ <type-selector>? <subclass-selector>* [ <pseudo-element-selector> <pseudo-class-selector>* ]* ]!
<combinator> = '>' | '+' | '~' | [ '||' ]


<type-selector> = <wq-name> | <ns-prefix>? '*'
<subclass-selector> = <id-selector> | <class-selector> | <attribute-selector> | <pseudo-class-selector>
<pseudo-element-selector> = ':' <pseudo-class-selector>
<pseudo-class-selector> = ':' <ident-token> | ':' <function-token> <any-value> ')'


<wq-name> = <ns-prefix>? <ident-token>
<ns-prefix> = [ <ident-token> | '*' ]? |
<id-selector> = <hash-token>
<class-selector> = '.' <ident-token>
<attribute-selector> = '[' <wq-name> ']' | '[' <wq-name> <attr-matcher> [ <string-token> | <ident-token> ] <attr-modifier>? ']'


<attr-matcher> = [ '~' | | | '^' | '$' | '*' ]? '='
<attr-modifier> = i | s

Exemples

Exemple fonctionnant pour les différents navigateurs

HTML

<header>
  <p>Voici un paragraphe dans un en-tête.</p>
</header>

<main>
  <ul>
    <li><p>Mon premier élément de</p><p>liste</p></li>
    <li><p>Mon deuxième élément de</p><p>liste</p></li>
  </ul>
</main>

<footer>
  <p>Et un paragraphe de pied de page</p>
</footer>

CSS

:-webkit-any(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}

:-moz-any(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}
:is(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}

JavaScript

let matchedItems;

try {
  matchedItems = document.querySelectorAll(':is(header, main, footer) p');
} catch(e) {
  try {
    matchedItems = document.querySelectorAll(':matches(header, main, footer) p');
  } catch(e) {
    try {
      matchedItems = document.querySelectorAll(':-webkit-any(header, main, footer) p');
    } catch(e) {
      try {
        matchedItems = document.querySelectorAll(':-moz-any(header, main, footer) p');
      } catch(e) {
        console.log('Votre navigateur ne prend pas en charge :is(), :matches() ou :any()');
      }
    }
  }
}

for(let i = 0; i < matchedItems.length; i++) {
  applyHandler(matchedItems[i]);
}

function applyHandler(elem) {
  elem.addEventListener('click', function(e) {
    alert('Ce paragraphe est à l\'intérieur d\'un élément ' + e.target.parentNode.nodeName);
  });
}

Simplifier les listes de sélecteurs

La pseudo-classe :matches() permet de simplifier largement les sélecteurs CSS. Ainsi, la règle suivante :

/* les listes non ordonnées sur 3 niveaux ou plus */
/* utilisent un carré comme puce */
ol ol ul,     ol ul ul,     ol menu ul,     ol dir ul,
ol ol menu,   ol ul menu,   ol menu menu,   ol dir menu,
ol ol dir,    ol ul dir,    ol menu dir,    ol dir dir,
ul ol ul,     ul ul ul,     ul menu ul,     ul dir ul,
ul ol menu,   ul ul menu,   ul menu menu,   ul dir menu,
ul ol dir,    ul ul dir,    ul menu dir,    ul dir dir,
menu ol ul,   menu ul ul,   menu menu ul,   menu dir ul,
menu ol menu, menu ul menu, menu menu menu, menu dir menu,
menu ol dir,  menu ul dir,  menu menu dir,  menu dir dir,
dir ol ul,    dir ul ul,    dir menu ul,    dir dir ul,
dir ol menu,  dir ul menu,  dir menu menu,  dir dir menu,
dir ol dir,   dir ul dir,   dir menu dir,   dir dir dir {
  list-style-type: square;
}

pourra être remplacée par :

/* les listes non ordonnées sur 3 niveaux ou plus */
/* utilisent un carré comme puce */
:matches(ol, ul, menu, dir) :matches(ol, ul, menu, dir) ul,
:matches(ol, ul, menu, dir) :matches(ol, ul, menu, dir) menu,
:matches(ol, ul, menu, dir) :matches(ol, ul, menu, dir) dir {
  list-style-type: square;
}

En revanche, on n'utilisera pas la forme suivante (cf. la section qui suit sur les performances) :

:matches(ol, ul, menu, dir) :matches(ol, ul, menu, dir) :matches(ul, menu, dir) {
  list-style-type: square;
}

Simplifier les sélecteurs de section

La pseudo-classe :matches est particulièrement utile lorsqu'on manipule les sections et en-têtes HTML5. <section>, <article>, <aside> et <nav> étant souvent imbriqués les uns dans les autres, les mettre en forme (sans :matches()) s'avèrerait plutôt compliqué.

Ainsi, sans :matches(), si on veut mettre en forme les éléments <h1> à différents niveaux, on obtient des règles plutôt compliquées :

/* Niveau 0 */
h1 {
  font-size: 30px;
}
/* Niveau 1 */
section h1, article h1, aside h1, nav h1 {
  font-size: 25px;
}
/* Niveau 2 */
section section h1, section article h1, section aside h1, section nav h1,
article section h1, article article h1, article aside h1, article nav h1,
aside section h1, aside article h1, aside aside h1, aside nav h1,
nav section h1, nav article h1, nav aside h1, nav nav h1 {
  font-size: 20px;
}
/* Niveau 3 */
/* … j'ai abandonné */

Avec :is(), c'est plus simple :

/* Niveau 0 */
h1 {
  font-size: 30px;
}
/* Niveau 1 */
:is(section, article, aside, nav) h1 {
  font-size: 25px;
}
/* Niveau 2 */
:is(section, article, aside, nav)
:is(section, article, aside, nav) h1 {
  font-size: 20px;
}
/* Niveau 3 */
:is(section, article, aside, nav)
:is(section, article, aside, nav)
:is(section, article, aside, nav) h1 {
  font-size: 15px;
}

Éviter les problèmes d'invalidation pour les listes de sélecteur

À la différence des listes de sélecteurs, la pseudo-classe :is() ne devient pas invalide lorsqu'un des sélecteurs passé en argument n'est pas pris en charge par le navigateur.

:is(:valide, :incompatible) {
  ...
}

sera analysé sans problème et permettra de cibler via le sélecteur :valide même si les navigateurs ne prennent pas en charge le sélecteur :incompatible. En revanche :

:valide, :incompatible {
  ...
}

ne sera pas appliqué par le moteur car ce sera considéré invalide, même si :valide est pris en charge par le navigateur.

Notes

Problèmes de performances avec any(): et la spécificité

bug 561154 suit un problème de spécificité relatif à :-moz-any(). L'implémentation  place :-moz-any() dans la catégorie des règles universelles, ce qui signifie que si on l'utilise comme sélecteur le plus à droite, ce sera plus lent que d'utiliser un sélecteur d'identifiant, de classe ou de balise comme premier sélecteur.

Ainsi :

.a > :-moz-any(.b, .c)

sera plus lent que

.a > .b, .a > .c

et cette dernière version sera plus rapide :

:-moz-any(.a, .d) > .b, :-moz-any(.a, .d) > .c

:is() doit permettre de corriger de tels problèmes.

Spécifications

Spécification État Commentaires
Selectors Level 4
La définition de ':is()' dans cette spécification.
Version de travail Définition initiale.

Compatibilité des navigateurs

Update compatibility data on GitHub
OrdinateurMobile
ChromeEdgeFirefoxInternet ExplorerOperaSafariWebview AndroidChrome pour AndroidFirefox pour AndroidOpera pour AndroidSafari sur iOSSamsung Internet
:is()Chrome Support complet 66
Notes Autre nom Désactivée
Support complet 66
Notes Autre nom Désactivée
Notes Has issues with combinators (see bug 842157).
Autre nom Cette fonctionnalité utilise le nom non-standard : :matches()
Désactivée From version 66: this feature is behind the Experimental Web Platform Features preference (needs to be set to enabled). To change preferences in Chrome, visit chrome://flags.
Support complet 12
Notes Autre nom
Notes Doesn't support combinators.
Autre nom Cette fonctionnalité utilise le nom non-standard : :-webkit-any()
Edge Aucun support NonFirefox Support complet 4
Notes Autre nom
Support complet 4
Notes Autre nom
Notes Doesn't support combinators.
Notes See bug 906353
Autre nom Cette fonctionnalité utilise le nom non-standard : :-moz-any()
IE Aucun support NonOpera Support complet 53
Notes Autre nom Désactivée
Support complet 53
Notes Autre nom Désactivée
Notes Has issues with combinators (see bug 842157).
Autre nom Cette fonctionnalité utilise le nom non-standard : :matches()
Désactivée From version 53: this feature is behind the Experimental Web Platform Features preference (needs to be set to enabled).
Support complet Oui
Notes Autre nom
Notes Doesn't support combinators.
Autre nom Cette fonctionnalité utilise le nom non-standard : :-webkit-any()
Safari Support complet 9
Autre nom
Support complet 9
Autre nom
Autre nom Cette fonctionnalité utilise le nom non-standard : :matches()
Support complet 5
Notes Autre nom
Notes Doesn't support combinators.
Autre nom Cette fonctionnalité utilise le nom non-standard : :-webkit-any()
WebView Android Support complet Oui
Notes Autre nom
Support complet Oui
Notes Autre nom
Notes Doesn't support combinators.
Autre nom Cette fonctionnalité utilise le nom non-standard : :-webkit-any()
Chrome Android Support complet 66
Notes Autre nom Désactivée
Support complet 66
Notes Autre nom Désactivée
Notes Has issues with combinators (see bug 842157).
Autre nom Cette fonctionnalité utilise le nom non-standard : :matches()
Désactivée From version 66: this feature is behind the Experimental Web Platform Features preference (needs to be set to enabled). To change preferences in Chrome, visit chrome://flags.
Support complet 18
Notes Autre nom
Notes Doesn't support combinators.
Autre nom Cette fonctionnalité utilise le nom non-standard : :-webkit-any()
Firefox Android Support complet 4
Notes Autre nom
Support complet 4
Notes Autre nom
Notes Doesn't support combinators.
Notes See bug 906353
Autre nom Cette fonctionnalité utilise le nom non-standard : :-moz-any()
Opera Android Support complet 47
Notes Autre nom Désactivée
Support complet 47
Notes Autre nom Désactivée
Notes Has issues with combinators (see bug 842157).
Autre nom Cette fonctionnalité utilise le nom non-standard : :matches()
Désactivée From version 47: this feature is behind the Experimental Web Platform Features preference (needs to be set to enabled).
Support complet Oui
Notes Autre nom
Notes Doesn't support combinators.
Autre nom Cette fonctionnalité utilise le nom non-standard : :-webkit-any()
Safari iOS Support complet 9
Autre nom
Support complet 9
Autre nom
Autre nom Cette fonctionnalité utilise le nom non-standard : :matches()
Support complet 5
Notes Autre nom
Notes Doesn't support combinators.
Autre nom Cette fonctionnalité utilise le nom non-standard : :-webkit-any()
Samsung Internet Android Aucun support Non

Légende

Support complet  
Support complet
Aucun support  
Aucun support
Voir les notes d'implémentation.
Voir les notes d'implémentation.
Une action explicite de l'utilisateur est nécessaire pour activer cette fonctionnalité.
Une action explicite de l'utilisateur est nécessaire pour activer cette fonctionnalité.
Cette fonctionnalité utilise un nom non-standard.
Cette fonctionnalité utilise un nom non-standard.

Voir aussi

Étiquettes et contributeurs liés au document

Contributeurs à cette page : SphinxKnight, mdnwebdocs-bot, tonybengue, Dralyab
Dernière mise à jour par : SphinxKnight,