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.