Kurs HTML

10.7. Pseudoklasa negacji (:not())

Wprowadzenie: Wykluczanie elementów z selekcji

Czasami chcemy zastosować styl do wszystkich elementów danego typu, **z wyjątkiem** niektórych, które spełniają określone kryteria. Zamiast tworzyć skomplikowane selektory lub nadpisywać style, możemy użyć pseudoklasy negacji :not().

Pseudoklasa :not() przyjmuje jako argument **prosty selektor** (lub listę prostych selektorów oddzielonych przecinkami w nowszych wersjach CSS) i wybiera elementy, które **nie pasują** do tego selektora.

Uwaga: Prosty selektor to selektor typu, selektor uniwersalny (*), selektor atrybutu, selektor klasy lub selektor ID. Nie można zagnieżdżać :not() ani używać w nim pseudoelementów.

Składnia i przykłady

Składnia jest prosta: selektor:not(selektor_do_wykluczenia).

<div class="container">
  <p>Zwykły paragraf.</p>
  <p class="special">Paragraf specjalny.</p>
  <p id="unique">Paragraf unikalny.</p>
  <p class="special note">Paragraf specjalny z notatką.</p>
  <div>Inny element div.</div>
</div>
/* Wybierz wszystkie paragrafy (p) w .container, */
/* które NIE mają klasy .special */
.container p:not(.special) {
  color: gray;
}

/* Wybierz wszystkie elementy w .container, */
/* które NIE są paragrafami (p) */
.container *:not(p) {
  border: 1px solid blue;
}

/* Wybierz wszystkie paragrafy (p), */
/* które NIE mają ID #unique */
p:not(#unique) {
  margin-bottom: 10px;
}

/* Wybierz wszystkie paragrafy (p), */
/* które NIE mają klasy .special ANI .note (wymaga nowszych przeglądarek) */
/* Starsze przeglądarki wymagają łańcucha: p:not(.special):not(.note) */
.container p:not(.special, .note) {
    /* W nowszych CSS można podać listę */
    /* font-style: italic; */
}

/* Łańcuchowe :not() dla starszych przeglądarek */
.container p:not(.special):not(.note) {
    font-style: italic;
}

W powyższym przykładzie:

  • Pierwszy i trzeci paragraf (bez klasy .special) będą miały szary kolor.
  • Element div wewnątrz .container otrzyma niebieską ramkę, bo nie jest paragrafem.
  • Wszystkie paragrafy oprócz tego z ID #unique otrzymają dolny margines.
  • Pierwszy paragraf ("Zwykły paragraf") otrzyma styl kursywy, ponieważ nie ma ani klasy .special, ani .note.

Łączenie :not() z innymi selektorami

Pseudoklasę :not() można łączyć z innymi selektorami i pseudoklasami, aby tworzyć bardziej złożone warunki wykluczenia.

/* Wybierz wszystkie elementy li, które NIE są pierwszym dzieckiem */
li:not(:first-child) {
  margin-top: 5px; /* Dodaj odstęp do wszystkich oprócz pierwszego */
}

/* Wybierz wszystkie linki, które NIE są linkami odwiedzonymi */
a:not(:visited) {
  /* To samo co a:link */
}

/* Wybierz inputy tekstowe, które NIE są wyłączone */
input[type="text"]:not(:disabled) {
  background-color: white;
}

/* Wybierz elementy, które NIE są obrazkami (img) ANI linkami (a) */
*:not(img):not(a) {
    /* ... */
}

Zadania praktyczne

Zadanie 1 (z rozwiązaniem)

Stwórz listę ul z kilkoma elementami li. Użyj :not(), aby nadać tło wszystkim elementom listy **z wyjątkiem ostatniego**.

Rozwiązanie:

HTML:

<ul class="task-list">
  <li>Element 1</li>
  <li>Element 2</li>
  <li>Element 3 (ostatni)</li>
</ul>

CSS:

.task-list li {
    padding: 5px;
}

.task-list li:not(:last-child) { /* Wybiera li, które NIE są ostatnim dzieckiem */
  background-color: lightcyan;
}

Efekt: Elementy 1 i 2 będą miały jasnoniebieskie tło, a ostatni element (Element 3) pozostanie bez tła.

Zadanie 2 (do samodzielnego wykonania)

Stwórz kilka przycisków button, jednemu z nich nadaj klasę .cancel. Użyj :not(), aby nadać niebieskie tło wszystkim przyciskom, które **nie mają** klasy .cancel.

Zadanie 3 (do samodzielnego wykonania)

Stwórz kilka pól input (text, email, password). Użyj :not(), aby nadać specjalne obramowanie wszystkim polom input, które **nie są** typu password.

FAQ - Najczęściej zadawane pytania

Czego nie mogę umieścić wewnątrz :not()?

Nie można zagnieżdżać pseudoklasy :not() (np. :not(:not(...)) jest niepoprawne). Nie można również używać wewnątrz niej pseudoelementów (np. :not(::before) jest niepoprawne). Argumentem musi być prosty selektor lub, w nowszych specyfikacjach CSS, lista prostych selektorów oddzielonych przecinkami.

Czy :not() wpływa na specyficzność selektora?

Tak. Specyficzność pseudoklasy :not() jest równa specyficzności **najbardziej specyficznego** selektora znajdującego się na liście argumentów. Na przykład, specyficzność div:not(.klasa) jest sumą specyficzności selektora typu (div) i selektora klasy (.klasa).

Czy mogę podać wiele selektorów do wykluczenia?

Tak, w nowszych wersjach CSS (Selectors Level 4) można podać listę selektorów oddzielonych przecinkami, np. p:not(.klasa1, .klasa2, #id). Wybierze to paragrafy, które nie mają ani klasy .klasa1, ani .klasa2, ani ID #id. W starszych przeglądarkach trzeba było łączyć wiele :not(): p:not(.klasa1):not(.klasa2):not(#id).

Czy :not(*) ma sens?

Nie, :not(*) nigdy niczego nie wybierze, ponieważ selektor uniwersalny * pasuje do każdego elementu, więc warunek "nie pasuje do *" nigdy nie będzie spełniony.