O... nie pogadamy dziś! Oj, przepraszam. O "nie" dziś pogadamy. Oczywiście wpis nie będzie naszpikowany negatywnymi treściami. Pobajerowałem też trochę w tytule i nie będę wcielał się w osobistego kołcza nauczającego jak być asertywnym. Pogadamy o "nie", czyli o pseudoklasie :not. Choć nadającej pejoratywny wydźwięk selektorom w CSS, to czasem bardzo pomocnej, niczym game changer. Ale dziś o jej mniej typowych rolach.
Nie za dużo?
Argumentem pseudoklasy :not jest selektor w prostej postaci. Możemy użyć pojedynczego tagu, id elementu, klasy, pseudoklasy, atrybutu lub selektora uniwersalnego (to gwiazdka zastępująca każdy element). Co to oznacza? Ni mniej, ni więcej, niż to, że nie możemy przekazać kilku argumentów, czyli składnia:
:not(.klasa1,.klasa2)
jest niepoprawna. I to jest oczywiste. Ale selektor ma być również w prostej postaci, czyli chcąc wybrać wszystkie elementy, które nie są SPAN z klasą klasa1, nie możemy zrobić tak:
:not(span.klasa1)
bo mamy tu do czynienia z selektorem złożonym (z tagu i klasy).
Przykład:
<span class="klasa1">Tekst 1</span>
<p>Tekst 2</p>
+
:not(span.klasa1) {
color: #f00;
}
W tym przypadku tekst w paragrafie wcale nie stanie się czerwony, bo nie zajdzie negacja złożonego selektora (oczywiście tekst w SPAN też nie stanie się czerwony, bo pseudoklasa nie działa odwrotnie niż powinna, lecz w ogóle nie działa).
Skoro tak nie działa, to może rozdzielimy argumenty na dwa odrębne, proste selektory i zadziała?
:not(span):not(.klasa1) {
color: #f00;
}
Nie działa? Działa (łączenie pseudoklas :not jest dozwolone), ale obydwa teksty są czerwone. A to pech!
Jeśli teraz zaczniesz rozbijać problem na mniejsze i sprawdzisz:
:not(span) {
color: #f00;
}
to okaże się, że tekst w P, ale też i w SPAN nadal są czerwone! Nie zmieni też nic dodanie gwiazdki przed :not, bo w tym przypadku obydwa takie selektory są równoznaczne.
Dlaczego tak się dzieje? Przede wszystkim - pseudoklasa działa. Dla P działa bezpośrednio, dla SPAN... również. Możesz pomyśleć sobie: "Jak to działa dla SPAN, skoro nie działa?". No ale nie zapominaj o dziedziczeniu. Tak więc bezpośrednio dla SPAN selektor nie nadał koloru czerwonego, ale selektor zadziałał dla rodzica SPAN, którym w naszym przykładzie jest BODY. BODY więc zyskało czerwony kolor tekstu, a SPAN ten kolor odziedziczył. Nieźle, co? Gdybyś chciał "poprawić" działanie tego selektora, to w tym przypadku należałoby go utworzyć w postaci:
body :not(span) {
color: #f00;
}
Nie wszystko na raz!
Inne ciekawe zachowanie, a raczej użycie pseudo klasy :not, to selektor :not(:hover). Za przykład niech posłuży:
span:not(:hover) {
background: #f00;
}
który na pierwszy rzut oka może wydawać się po prostu ekwiwalentem dla:
span {
background: #f00;
}
I tu Cię zaskoczę. Albo i nie. Pierwszy selektor jest zaledwie połową tego drugiego. Jeśli ktoś w tej chwili szuka drugiej połówki, to wygląda ona tak:
span:hover {
background: #f00;
}
Tak więc ten drugi selektor mówi o SPAN, zarówno bez, jak i z :hover. Trzeci tylko o stanie :hover, a pierwszy o SPAN tylko i wyłącznie w stanie bez :hover.
Nie ma nic!
I trochę mniej praktycznych przykładów, których pewnie nie zastosujesz:
:not(*) {
color: #f00;
}
Ten selektor dotyczy wszystkich tagów, które... nie są żadnym tagiem. Czyli z całego zbioru tagów (pamiętaj, że "nic" przed średnikiem jest równoznaczne z *) eliminujemy wszystkie tagi. Zostaje więc zbiór pusty.
Wspomniałem też, że argumentem może być pseudoklasa (pseudoklasa, nie pseudoelement). Ale, ale! Nie może być nim pseudoklasa :not:
:not(:not(span)) {
color: #f00;
}
Choć wydawałoby się, że takie podwójne zagłębienie stanowi ekwiwalent dla:
span {
color: #f00;
}
Następny wpis za :not(długo). Do przeczytania!