Pseudoklasy

The CSS Podcast - 015: Pseudo-classes

Załóżmy, że masz formularz rejestracji adresu e-mail i chcesz, aby pole formularza adresu e-mail miało czerwone obramowanie, jeśli zawiera nieprawidłowy adres e-mail. Jak to zrobić? Możesz użyć pseudoklasy CSS :invalid, która jest jedną z wielu pseudoklas udostępnianych przez przeglądarkę.

Pseudoklasa umożliwia stosowanie stylów na podstawie zmian stanu i czynników zewnętrznych. Oznacza to, że projekt może reagować na działania użytkownika, np. na wpisanie nieprawidłowego adresu e-mail. Omówiliśmy je w module selektory, a w tym module znajdziesz więcej szczegółów na ich temat.

W przeciwieństwie do pseudoelementów, o których możesz dowiedzieć się więcej w poprzednim module, pseudoklasy odnoszą się do konkretnych stanów, w jakich może znajdować się element, a nie do ogólnego stylu części tego elementu.

Stany interaktywne

Poniższe pseudoklasy są stosowane ze względu na interakcję użytkownika ze stroną.

:hover

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 2.

Source

Jeśli użytkownik ma urządzenie wskazujące, takie jak mysz lub trackpad, i umieści kursor nad elementem, możesz użyć stanu :hover, aby zastosować style. To przydatny sposób na zasugerowanie, że z elementem można wejść w interakcję.

:active

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.

Source

Ten stan jest aktywowany, gdy użytkownik wchodzi w interakcję z elementem (np. klika go), zanim zwolni przycisk myszy. Jeśli używane jest urządzenie wskazujące, np. mysz, ten stan oznacza, że kliknięcie zostało rozpoczęte, ale nie zostało jeszcze zwolnione.

:focus, :focus-within:focus-visible

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.

Source

Jeśli element może zostać zaznaczony, np. <button>, możesz zareagować na ten stan za pomocą pseudoklasy :focus.

Możesz też reagować, gdy element podrzędny Twojego elementu zostanie zaznaczony za pomocą :focus-within.

Elementy, na których można ustawić fokus, takie jak przyciski, będą wyświetlać pierścień zaznaczenia, gdy są zaznaczone – nawet po kliknięciu. W takiej sytuacji deweloper zastosuje ten kod CSS:

button:focus {
    outline: none;
}

Ten kod CSS usuwa domyślny pierścień zaznaczenia przeglądarki, gdy element zostaje zaznaczony, co stanowi problem z dostępnością dla użytkowników, którzy poruszają się po stronie internetowej za pomocą klawiatury. Jeśli nie ma stylu zaznaczenia, użytkownicy nie będą mogli śledzić, gdzie znajduje się zaznaczenie podczas korzystania z klawisza Tab. Za pomocą właściwości :focus-visible możesz zastosować styl zaznaczenia, gdy element zostanie zaznaczony za pomocą klawiatury, a za pomocą reguły outline: none możesz zapobiec temu, gdy wchodzi w interakcję z urządzeniem wskazującym.

button:focus {
    outline: none;
}

button:focus-visible {
    outline: 1px solid black;
}

:target

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.3.

Source

Pseudoklasa :target wybiera element, który ma atrybut id pasujący do fragmentu adresu URL. Załóżmy, że masz taki kod HTML:

<article id="content">
    <!-- ... -->
</article>

Style możesz dołączyć do tego elementu, gdy adres URL zawiera #content.

#content:target {
    background: yellow;
}

Jest to przydatne do wyróżniania obszarów, do których można było przejść za pomocą linku, np. głównej treści w witrynie, przy użyciu linku do pomijania.

Stany historyczne

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 1.

Source

Pseudoklasę :link można zastosować do dowolnego elementu <a>, który ma wartość href, która nie została jeszcze odwiedzona.

:visited

Możesz zastosować styl do linku, który został już odwiedzony przez użytkownika, za pomocą pseudoklasy :visited. Jest to stan przeciwny do :link, ale z względów bezpieczeństwa masz do dyspozycji mniej właściwości CSS. Możesz zmieniać styl elementów color, background-color,border-color, outline-color oraz kolor elementów SVG fillstroke.

Kolejność spraw

Jeśli zdefiniujesz styl :visited, może on zostać zastąpiony przez pseudoklasę linku o co najmniej takiej samej specyficzności. Z tego powodu zalecamy używanie reguły LVHA do stylizowania linków za pomocą pseudoklas w określonej kolejności: :link, :visited, :hover, :active.

a:link {}
a:visited {}
a:hover {}
a:active {}

Stany formularza

Poniższe pseudoklasy mogą wybierać elementy formularza w różnych stanach, w jakich mogą się one znajdować podczas interakcji z nimi.

:disabled:enabled

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 3.1.

Source

Jeśli element formularza, np. <button>, jest wyłączony przez przeglądarkę, możesz skorzystać z pseudoklasy :disabled, aby uzyskać dostęp do tego stanu. Klasa :enabled jest dostępna dla stanu przeciwnego, ale elementy formularza są też domyślnie :enabled, więc możesz nie potrzebować tej klasy.

:checked:indeterminate

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 3.1.

Source

Pseudoklasa :checked jest dostępna, gdy obsługujący element formularza, taki jak pole wyboru lub przycisk opcji, jest zaznaczony.

Stan :checked jest stanem binarnym (prawda lub fałsz), ale pola wyboru mają stan pośredni, gdy nie są zaznaczone ani odznaczone. Jest to tzw. stan :indeterminate.

Przykładem takiego stanu jest sytuacja, w której masz element sterujący „Zaznacz wszystko”, który zaznacza wszystkie pola wyboru w grupie. Jeśli użytkownik odznaczy jedno z tych pól wyboru, główne pole wyboru nie będzie już oznaczać, że „wszystkie” są zaznaczone, więc powinno przejść w stan nieokreślony.

Element <progress> ma też stan nieokreślony, który można ostylować. Często stosuje się paski, aby wskazać, że nie wiadomo, ile jeszcze brakuje.

:placeholder-shown

Browser Support

  • Chrome: 47.
  • Edge: 79.
  • Firefox: 51.
  • Safari: 9.

Source

Jeśli pole formularza ma atrybut placeholder i nie ma wartości, dołączenie stylów do tego stanu jest możliwe za pomocą pseudoklasy :placeholder-shown. Gdy tylko w polu pojawią się treści, niezależnie od tego, czy mają one wartość placeholder, ten stan przestanie obowiązywać.

Stany weryfikacji

Browser Support

  • Chrome: 10.
  • Edge: 12.
  • Firefox: 4.
  • Safari: 5.

Source

Na walidację formularza HTML możesz odpowiadać za pomocą pseudoklas, takich jak :valid, :invalid:in-range. Pseudoklasy :valid i :invalid są przydatne w kontekstach, takich jak pole adresu e-mail, które ma znak pattern, który musi być dopasowany, aby pole było prawidłowe. Ten stan prawidłowej wartości może być wyświetlany użytkownikowi, co pomoże mu zrozumieć, że może bezpiecznie przejść do następnego pola.

Klasa pseudoelementu :in-range jest dostępna, jeśli dane wejściowe mają atrybuty min i max, np. dane liczbowe i wartość mieści się w tych granicach.

W przypadku formularzy HTML możesz określić, że pole jest wymagane, za pomocą atrybutu required. Klasa pseudoelementu :required będzie dostępna w przypadku wymaganych pól. Pola, które nie są wymagane, można wybrać za pomocą pseudoklasy :optional.

Wybieranie elementów według indeksu, kolejności i występowania

Istnieje grupa pseudoklas, które wybierają elementy na podstawie ich położenia w dokumencie.

:first-child:last-child

Browser Support

  • Chrome: 4.
  • Edge: 12.
  • Firefox: 3.
  • Safari: 3.1.

Source

Jeśli chcesz znaleźć pierwszy lub ostatni element, możesz użyć :first-child i :last-child. Te pseudoklasy zwracają pierwszy lub ostatni element w grupie elementów pokrewnych.

:only-child

Browser Support

  • Chrome: 2.
  • Edge: 12.
  • Firefox: 1.5.
  • Safari: 3.1.

Source

Możesz też wybrać elementy, które nie mają elementów równorzędnych, za pomocą pseudoklasy :only-child.

:first-of-type:last-of-type

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 3.5.
  • Safari: 3.1.

Source

Możesz wybrać tagi :first-of-type:last-of-type, które na pierwszy rzut oka działają tak samo jak tagi :first-child:last-child, ale weź pod uwagę ten kod HTML:

<div class="my-parent">
    <p>A paragraph</p>
    <div>A div</div>
    <div>Another div</div>
</div>

A ta usługa porównywania cen:

.my-parent div:first-child {
    color: red;
}

Żaden element nie będzie czerwony, ponieważ pierwszym elementem podrzędnym jest akapit, a nie element div. W tym kontekście przydatna jest pseudoklasa :first-of-type.

.my-parent div:first-of-type {
    color: red;
}

Chociaż pierwszy element <div> jest drugim elementem podrzędnym, jest on pierwszym elementem tego typu w elemencie .my-parent, więc zgodnie z tą regułą będzie miał kolor czerwony.

:nth-child:nth-of-type

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 3.5.
  • Safari: 3.1.

Source

Nie musisz ograniczać się do pierwszych i ostatnich elementów podrzędnych ani typów. Pseudoklasy :nth-child:nth-of-type umożliwiają określenie elementu, który znajduje się pod określonym indeksem. Indeksowanie w selektorach CSS zaczyna się od 1.

Pseudoklasy :nth-last-child() i :nth-last-of-type() liczą od końca, a nie od początku.

Do tych pseudoklas możesz też przekazywać więcej niż tylko indeks. Jeśli chcesz wybrać wszystkie elementy parzyste, możesz użyć :nth-child(even).

Możesz też tworzyć bardziej złożone selektory, które znajdują elementy w regularnych odstępach, używając mikroskładni An+B.

li:nth-child(3n+3) {
    background: yellow;
}

Ten selektor wybiera co trzeci element, począwszy od elementu 3. Znak n w tym wyrażeniu to indeks, który zaczyna się od zera, a 3 (3n) to liczba, przez którą mnożysz ten indeks.

Załóżmy, że masz 7 <li>. Pierwszym wybranym elementem jest 3, ponieważ 3n+3 przekłada się na (3 * 0) + 3. W kolejnej iteracji zostanie wybrany element 6, ponieważ wartość n wzrosła do 1, a więc (3 * 1) + 3). To wyrażenie działa zarówno w przypadku :nth-child, jak i :nth-of-type.

:nth-child():nth-last-child() obsługują też składnię „of S”, która umożliwia filtrowanie dopasowań za pomocą selektora, podobnie jak :nth-of-type(). Funkcja li:nth-of-type(even) jest odpowiednikiem funkcji :nth-child(even of li). O ile :nth-of-type pozwala filtrować tylko według typu elementu (np. li lub p), składnia „of S” umożliwia filtrowanie według dowolnego selektora.

Jeśli masz tabelę, możesz dodać paski do co drugiego wiersza. Możesz kierować reklamy na co drugi wiersz za pomocą funkcjitr:nth-child(even), ale nie działa to, jeśli filtrujesz niektóre wiersze. Jeśli filtrujesz, stosując atrybut hidden, możesz dodać of :not([hidden]) do selektora, aby wstępnie odfiltrować ukryte elementy przed wybraniem parzystych wierszy.

tr:nth-child(even of :not([hidden])){
  background: lightgrey;
}

Możesz wypróbować ten rodzaj selektora w tym testerze selektora nth-child lub tym narzędziu do wyboru ilości.

:only-of-type

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 3.5.
  • Safari: 3.1.

Source

Możesz też znaleźć jedyny element określonego typu w grupie elementów równorzędnych za pomocą selektora :only-of-type. Jest to przydatne, jeśli chcesz wybrać listy z tylko jednym elementem lub znaleźć jedyny element w tekście, który jest pogrubiony.

Wyszukiwanie pustych elementów

Czasami przydatne może być zidentyfikowanie całkowicie pustych elementów. W tym celu również istnieje pseudoklasa.

:empty

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 3.1.

Source

Jeśli element nie ma elementów podrzędnych, stosuje się do niego pseudoklasę :empty. Elementy podrzędne to nie tylko elementy HTML czy węzły tekstowe, ale też białe znaki, co może być mylące podczas debugowania poniższego kodu HTML i zastanawiania się, dlaczego nie działa on z funkcją :empty:

<div>
</div>

Dzieje się tak, ponieważ między otwierającym i zamykającym znakiem <div> jest trochę białych znaków, więc :empty nie będzie działać.

Klasa pseudo :empty może być przydatna, jeśli masz niewielką kontrolę nad kodem HTML i chcesz ukryć puste elementy, np. edytor treści WYSIWYG. W tym przypadku osoba edytująca dodała niepotrzebny pusty akapit.

<article class="post">
 <p>Donec ullamcorper nulla non metus auctor fringilla.</p>
 <p></p>
 <p>Curabitur blandit tempus porttitor.</p>
</article>

Dzięki :empty możesz znaleźć i ukryć takie informacje.

.post :empty {
    display: none;
}

Znajdowanie i wykluczanie wielu elementów

Niektóre pseudoklasy pomagają pisać bardziej zwięzły kod CSS.

:is()

Browser Support

  • Chrome: 88.
  • Edge: 88.
  • Firefox: 78.
  • Safari: 14.

Source

Jeśli chcesz znaleźć wszystkie elementy podrzędne h2, liimg w elemencie .post, możesz napisać taką listę selektorów:

.post h2,
.post li,
.post img {
    
}

Za pomocą pseudoklasy :is() możesz napisać bardziej zwięzłą wersję:

.post :is(h2, li, img) {
    /* ... */
}

Pseudoklasa :is jest nie tylko bardziej zwarta niż lista selektorów, ale też bardziej tolerancyjna. W większości przypadków, jeśli na liście selektorów wystąpi błąd lub nieobsługiwany selektor, cała lista selektorów przestanie działać. Jeśli w pseudoklasie :is wystąpi błąd w przekazanych selektorach, zignoruje on nieprawidłowy selektor, ale użyje tych, które są prawidłowe.

:not()

Browser Support

  • Chrome: 1.
  • Edge: 12.
  • Firefox: 1.
  • Safari: 3.1.

Source

Możesz też wykluczyć elementy za pomocą pseudoklasy :not(). Możesz na przykład użyć go do określenia stylu wszystkich linków, które nie mają atrybutu class.

a:not([class]) {
    color: blue;
}

:notKlasa pseudoelementu może też pomóc w zwiększeniu dostępności. Na przykład element <img> musi mieć element alt, nawet jeśli jest to pusta wartość. Możesz więc napisać regułę CSS, która dodaje gruby czerwony kontur do nieprawidłowych obrazów:

img:not([alt]) {
    outline: 10px red;
}

:has()

Co zrobić, jeśli chcesz zastosować styl do elementów na podstawie tego, co zawierają? Możesz do tego użyć pseudoklasy :has(). Możesz na przykład zastosować style do przycisków zawierających ikony.

 button:has(svg) {
  /* ... */
}

W najprostszej konfiguracji, takiej jak w poprzednim przykładzie, :has() można traktować jako selektor nadrzędny. Możesz też użyć selektora pasującego elementu nadrzędnego w połączeniu z innymi selektorami, aby kierować reklamy na inne elementy.

form:has(input:valid) label {
  font-weight: bold;
}

form:has(input:valid) label::after {
  content: "✅";
}

W tym przykładzie stosujemy style do elementu etykiety i pseudoelementu label::after, gdy element wejściowy formularza ma pseudoklasę valid.

Klasy pseudo :has() nie można zagnieżdżać w innej klasie :has(), ale można ją łączyć z innymi klasami pseudo.

:is(h1, h2, h3):has(a) {
   /* ... */
}

Lista selektorów jest bezwzględna, więc jeśli którykolwiek selektor na liście jest nieprawidłowy, wszystkie reguły stylu zostaną zignorowane.

.my-element:has(img, ::before) {
  /* any styles here will be discarded since pseudo elements can't be included in the :has() selector list */
}

Sprawdź swoją wiedzę

Sprawdź swoją wiedzę o klasach pozornych

Pseudoklasy działają tak, jakby do elementu została dynamicznie zastosowana klasa, a pseudoelementy działają na samym elemencie.

Prawda
Zwróć uwagę na użycie pojedynczego lub podwójnego znaku : jako kluczowego znaku rozróżniającego w selektorze.
Fałsz
Pseudoelementy służą do określania części, a pseudoklasy do określania stanu.

Które z poniższych są funkcyjnymi pseudoklasami?

:is()
🎉
:target
Po pseudoklasach funkcyjnych występuje symbol (), co oznacza, że przyjmują one parametry.
:empty
Po pseudoklasach funkcyjnych występuje symbol (), co oznacza, że przyjmują one parametry.
:not()
🎉

Które z tych pseudoklas są wynikiem interakcji użytkownika?

:hover
🎉
:press
Spróbuj jeszcze raz.
:squeeze
Spróbuj jeszcze raz.
:target
🎉
:focus-within
🎉

Które z tych elementów są pseudoklasami stanu <form>?

:enabled
🎉
:fresh
Spróbuj jeszcze raz.
:indeterminate
🎉
:checked
🎉
:in-range
🎉
:loading
Spróbuj jeszcze raz.
:valid
🎉