La pseudo-classe :matches() 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). Cette version fonctionne comme :matches() mais nécessite l'utilisation de préfixes navigateur.

/* Sélectionne n'importe quel paragraphe au sein
   d'un header, d'un main ou d'un pied de page 
   et qui est survolé */
:matches(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,
:-webkit-any(header, main, footer) p:hover,
:matches(header, main, footer) p:hover {
  color: red;
  cursor: pointer;
}

Syntaxe

La syntaxe n'a pas été trouvée !

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

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

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

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

JavaScript

let matchedItems;

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 :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 :matches(), c'est plus simple :

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

Notes

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

Le 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

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

Spécifications

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

Compatibilité des navigateurs

FonctionnalitéChromeEdgeFirefoxInternet ExplorerOperaSafari
Support simple

66

121

15

122

43 Non Oui1

9

51

FonctionnalitéAndroid webviewChrome for AndroidEdge mobileFirefox for AndroidOpera AndroidiOS SafariSamsung Internet
Support simple

66

121

66

181

Non43 Oui1

9

51

Non

1. Supported as :-webkit-any.

2. Supported as :-ms-matches.

3. Supported as :-moz-any.

Voir aussi

 

Étiquettes et contributeurs liés au document

Étiquettes : 
Contributeurs à cette page : tonybengue, Dralyab, SphinxKnight
Dernière mise à jour par : tonybengue,