Puis-je écrire un sélecteur CSS sélectionnant des éléments n'ayant pas une certaine classe ou un certain attribut?

647

Je voudrais écrire une règle de sélection CSS qui sélectionne tous les éléments qui n'ont pas une certaine classe. Par exemple, étant donné le code HTML suivant:

<html class="printable">
    <body class="printable">
        <h1 class="printable">Example</h1>
        <nav>
            <!-- Some menu links... -->
        </nav>
        <a href="javascript:void(0)" onclick="javascript:self.print()">Print me!</a>
        <p class="printable">
            This page is super interresting and you should print it!
        </p>
    </body>
</html>

Je voudrais écrire un sélecteur qui sélectionne tous les éléments qui n'ont pas la classe "imprimable" qui, dans ce cas, sont les éléments nav et a .

Est-ce possible?

REMARQUE: dans le HTML réel où j'aimerais utiliser cela, il y aura beaucoup plus d'éléments qui n'ont pas la classe "imprimable" que moi (je réalise que c'est l'inverse dans l'exemple ci-dessus).

David Nordvall
la source

Réponses:

901

En règle générale, vous ajoutez un sélecteur de classe à la :not()pseudo-classe comme suit:

:not(.printable) {
    /* Styles */
}

:not([attribute]) {
    /* Styles */
}

Mais si vous avez besoin un meilleur support du navigateur (IE8 et anciens ne supportent pas :not(), vous êtes probablement mieux) de créer des règles de style pour les éléments qui faire avoir la classe « imprimable ». Si même cela n'est pas possible malgré ce que vous dites de votre balisage réel, vous devrez peut-être contourner cette limite.

Gardez à l'esprit que, selon les propriétés que vous définissez dans cette règle, certaines d'entre elles peuvent être héritées par des descendants qui le sont .printable ou les affecter d'une manière ou d'une autre. Par exemple, bien qu'il displayne soit pas hérité, la définition display: nonede a :not(.printable)l'empêchera, ainsi que tous ses descendants, de s'afficher, car il supprime complètement l'élément et son sous-arbre de la disposition. Vous pouvez souvent contourner cela en utilisant à la visibility: hiddenplace ce qui permettra aux descendants visibles de s'afficher, mais les éléments cachés affecteront toujours la mise en page comme ils l'ont fait à l'origine. Bref, soyez prudent.

BoltClock
la source
4
En tant que petite pépite d'informations, la prise en charge du navigateur pour les aspects multimédia du CSS est souvent la même pour tous les types de médias - si un navigateur ne prend pas en charge :not()à l'écran, il ne le supportera pas non plus en version imprimée.
BoltClock
19
Notez que :not()ne prend qu'un simple sélecteur ce qui signifie qu'il ne peut pas contenir de sélecteurs imbriqués comme :not(div .printable)- voir Syntaxe du sélecteur W3C
Steve Eynon
1
Je viens de l'essayer pour .active a: pas (.active a) ne fonctionnait pas pour moi. Mais, non: (.active)!
user2367418
Lorsque vous dites que cela n'a pas fonctionné pour vous, vous voulez probablement dire que cela n'a pas fonctionné pour vous , non? Cela ne signifie pas que cela ne fonctionne pas, c'est probablement un cas de spécificité - les propriétés de votre :not(.active)règle peuvent simplement avoir été remplacées par des propriétés de règle (s) avec une priorité plus élevée.
amn
1
@Kilves: Êtes-vous sûr de cela? La spécificité de :not()est celle de son argumentation, qui signifie :not(div)est également spécifique à div, :not(.cls)à .clset :not(#id)à #id.
BoltClock
180
:not([class])

En fait, cela sélectionnera tout ce qui n'a pas de classe css ( class="css-selector").

J'ai fait une démo jsfiddle

    h2 {color:#fff}
    :not([class]) {color:red;background-color:blue}
    .fake-class {color:green}
    <h2 class="fake-class">fake-class will be green</h2>
    <h2 class="">empty class SHOULD be white</h2>
    <h2>no class should be red</h2>
    <h2 class="fake-clas2s">fake-class2 SHOULD be white</h2>
    <h2 class="">empty class2 SHOULD be white</h2>
    <h2>no class2 SHOULD be red</h2>

Est-ce pris en charge? Oui: Caniuse.com (consulté le 02 janvier 2020) :

  • Soutien: 98,74%
  • Prise en charge partielle: 0,1%
  • Total: 98,84%

Édition drôle, j'étais googler pour l'opposé de: non. Négation CSS?

selector[class]  /* the oposite of :not[]*/
Milche Patern
la source
109

La :notpseudo-classe de négation

La pseudo-classe CSS de négation,, :not(X)est une notation fonctionnelle prenant un simple sélecteur X comme argument. Il correspond à un élément qui n'est pas représenté par l'argument. X ne doit pas contenir un autre sélecteur de négation.

Vous pouvez utiliser :notpour exclure tout sous-ensemble d'éléments correspondants, ordonné comme vous le feriez pour des sélecteurs CSS normaux.


Exemple simple: exclure par classe

div:not(.class)

Sélectionnerait tous les divéléments sans la classe.class

div:not(.class) {
  color: red;
}
<div>Make me red!</div>
<div class="class">...but not me...</div>


Exemple complexe: exclusion par type / hiérarchie

:not(div) > div

Sélectionnerait tous les divéléments qui ne sont pas des enfants d'un autrediv

div {
  color: black
}
:not(div) > div {
  color: red;
}
<div>Make me red!</div>
<div>
  <div>...but not me...</div>
</div>


Exemple complexe: enchaîner des pseudo-sélecteurs

À l'exception notable de l'impossibilité de chaîner / imbriquer des :notsélecteurs et des pseudo-éléments, vous pouvez les utiliser conjointement avec d'autres pseudo-sélecteurs.

div {
  color: black
}
:not(:nth-child(2)){
  color: red;
}
<div>
  <div>Make me red!</div>
  <div>...but not me...</div>
</div>


Prise en charge du navigateur , etc.

:notest un sélecteur de niveau CSS3 , la principale exception en termes de support est qu'il s'agit d' IE9 +

La spécification soulève également un point intéressant:

le :not()pseudo permet d'écrire des sélecteurs inutiles. Par exemple :not(*|*), qui ne représente aucun élément, ou foo:not(bar), qui est équivalent foomais avec une spécificité plus élevée.

SW4
la source
3
C'était un souper bien documenté et bien expliqué! #thumbsup
Jonathan Bredo Christensen
Ok, votre exemple :not(div) > divne fonctionnerait qu'avec des parents directs. Et les autres grands-pères?
FindOut_Quran
Super information! Juste ce dont j'avais besoin! Merci!
Jamie
9

Tout comme pour contribuer que les réponses ci-dessus de: not () peuvent être très efficaces sous des formes angulaires, plutôt que de créer des effets ou d'ajuster la vue / DOM,

input.ng-invalid:not(.ng-pristine) { ... your css here i.e. border-color: red; ...}

Garantit qu'au chargement de votre page, les champs de saisie ne montreront que les invalides (bordures ou arrière-plans rouges, etc.) s'ils ont des données ajoutées (c'est-à-dire qu'elles ne sont plus vierges) mais ne sont pas valides.

BaneStar007
la source
7

Exemple

  [class*='section-']:not(.section-name) {
    @include opacity(0.6);
    // Write your css code here
  }

// Opacity 0.6 all "section-" mais pas "section-name"

Hakan
la source
2

Vous pouvez utiliser le :not(.class)sélecteur comme mentionné précédemment.

Si vous vous souciez de la compatibilité d'Internet Explorer, je vous recommande d'utiliser http://selectivizr.com/ .

Mais n'oubliez pas de l'exécuter sous apache, sinon vous ne verrez pas l'effet.

MelkorNemesis
la source
3
Que voulez-vous dire l'exécuter sous apache? Selectivizr est une
bibliothèque
Il exécute la requête ajax - cela ne fonctionne pas sans serveur http.
MelkorNemesis
2

Utilisation de la :not()pseudo classe:

Pour tout sélectionner sauf un certain élément (ou éléments). Nous pouvons utiliser la :not() pseudo-classe CSS . La :not()pseudo-classe nécessite un CSSsélecteur comme argument. Le sélecteur appliquera les styles à tous les éléments à l'exception des éléments qui sont spécifiés comme argument.

Exemples:

/* This query selects All div elements except for   */
div:not(.foo) {
  background-color: red;
}


/* Selects all hovered nav elements inside section element except
   for the nav elements which have the ID foo*/
section nav:hover:not(#foo) {
  background-color: red;
}


/* selects all li elements inside an ul which are not odd */
ul li:not(:nth-child(odd)) { 
  color: red;
}
<div>test</div>
<div class="foo">test</div>

<br>

<section>
  <nav id="foo">test</nav>
  <nav>Hover me!!!</nav>
</section>
<nav></nav>

<br>

<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
</ul>

Nous pouvons déjà voir la puissance de cette pseudo-classe, elle nous permet d'affiner commodément nos sélecteurs en excluant certains éléments. De plus, cette pseudo classe augmente la spécificité du sélecteur . Par exemple:

/* This selector has a higher specificity than the #foo below */
#foo:not(#bar) {
  color: red;
}

/* This selector is lower in the cascade but is overruled by the style above */
#foo {
  color: green;
}
<div id="foo">"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
  in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</div>

Willem van der Veen
la source
0

Si vous voulez qu'un menu de classe spécifique ait un CSS spécifique si une classe manquante est connectée :

body:not(.logged-in) .menu  {
    display: none
}
Mihai
la source
-1

Comme d'autres l'ont dit, vous dites simplement: non (.class). Pour les sélecteurs CSS, je recommande de visiter ce lien, cela a été très utile tout au long de mon voyage: https://code.tutsplus.com/tutorials/the-30-css-selectors-you-must-memorize--net-16048

div:not(.success) {
  color: red;
}

La pseudo-classe de négation est particulièrement utile. Disons que je veux sélectionner toutes les divs, sauf celle qui a un id de conteneur. L'extrait ci-dessus gérera parfaitement cette tâche.

Ou, si je voulais sélectionner chaque élément (non conseillé) à l'exception des balises de paragraphe, nous pourrions faire:

*:not(p) {
  color: green;
}
HBhering
la source