Décrire ce qu'on veut cibler est souvent plus simple que décrire tout ce qu'on veut exclure. La pseudo-classe :not() inverse ce raisonnement : au lieu de lister les éléments à styliser, elle permet de partir d'un groupe large et d'en retirer une exception précise.
C'est un outil discret mais redoutablement pratique dès qu'une règle doit s'appliquer presque partout, à une exception près.
Définition
La pseudo-classe :not() cible tout élément qui NE correspond PAS au sélecteur passé entre parenthèses. Elle s'utilise comme n'importe quelle autre pseudo-classe, accolée à un sélecteur ou utilisée seule.
Exemple pratique
/* tous les boutons sauf celui avec la classe .actif */
.bouton:not(.actif) {
opacity: 0.7;
}
/* tous les paragraphes sauf le dernier de la liste */
p:not(:last-child) {
margin-bottom: 16px;
}
/* tous les champs sauf ceux désactivés */
input:not([disabled]) {
cursor: text;
}Le premier exemple illustre le cas le plus classique : plutôt que de styliser chaque bouton non actif un par un, :not(.actif) part du groupe entier des boutons et retire ceux qui portent la classe active. C'est particulièrement utile pour marquer visuellement tous les éléments d'une liste sauf le dernier, sans avoir à ajouter une classe supplémentaire dédiée à cette exception.
Accepter une liste depuis les navigateurs récents
Les versions récentes de CSS permettent de passer plusieurs sélecteurs à :not(), séparés par des virgules, ce qui évite d'enchaîner plusieurs :not() à la suite pour exclure plusieurs cas à la fois.
/* tous les liens sauf ceux actifs OU désactivés */
a:not(.actif, .desactive) {
color: #2d6cdf;
}Avant cette évolution, il fallait écrire a:not(.actif):not(.desactive), une chaîne de deux :not() qui produit exactement le même résultat mais reste plus lourde à lire.
| Objectif | Sélecteur |
|---|---|
| Tous les boutons sauf le dernier | .bouton:not(:last-child) |
| Tous les liens externes uniquement | a:not([href^="/"]) |
| Tous les champs actifs | input:not([disabled]) |
:not() correspond à celle de son argument, exactement comme :is(). Un :not() qui contient un id alourdit donc toute la règle, un point souvent oublié quand on manipule ce sélecteur.:not() pour simplifier une longue liste d'exceptions
Sans :not(), exclure plusieurs éléments d'une règle oblige souvent à écrire un Sélecteur CSS négatif de façon détournée, par exemple en ajoutant une classe supplémentaire sur tous les éléments concernés pour ensuite cibler ceux qui ne la portent pas. :not() évite ce détour en exprimant directement l'exception dans le sélecteur, ce qui garde le HTML plus propre et la feuille de style plus courte.
/* toutes les cartes sauf celle mise en avant */
.carte:not(.mise-en-avant) {
opacity: 0.85;
}
/* tous les liens de navigation sauf le lien courant */
.nav-lien:not([aria-current="page"]) {
color: #666;
}Le second exemple s'appuie sur un attribut d'accessibilité déjà présent dans un menu bien construit, plutôt que d'ajouter une classe .actif redondante. C'est un bon réflexe : avant d'ajouter une classe uniquement pour exclure un élément avec :not(), vérifiez si le HTML ne porte pas déjà l'information sous forme d'attribut. Comme :is() et :where(), :not() hérite de la Spécificité de son argument, un point à garder en tête pour éviter des surprises lors d'une surcharge ultérieure.
Questions fréquentes
:not() dans un autre :not() ?Oui, la spécification l'autorise, même si ce genre d'imbrication rend rapidement le sélecteur difficile à lire. Dans la pratique, il vaut mieux reformuler la logique autrement quand cela arrive, par exemple en extrayant une classe dédiée plutôt qu'en empilant les négations.
:not() peut-il cibler un pseudo-élément comme ::before ?Non, :not() n'accepte que des sélecteurs simples et composés, pas des pseudo-éléments, puisque ces derniers ne représentent pas un élément qui pourrait exister ou non dans le HTML. Cette limitation découle directement de la nature même des pseudo-éléments, qui ne correspondent à aucun nœud du DOM.
:not() et un simple sélecteur négatif imaginaire ?CSS n'a jamais eu de syntaxe négative en dehors de :not(). C'est justement ce qui en fait un outil unique : sans lui, il faudrait toujours cibler positivement chaque exception une par une.