Kurs HTML i CSS · Moduł 3: Podstawy CSS

Pseudo-klasy i pseudo-elementy CSS

6 min czytania ·
W tej lekcji4

Chcesz, żeby link złociał po najechaniu myszką, co drugi wiersz tabeli miał inne tło, a przed każdym nagłówkiem pojawiał się hieroglif - bez dopisywania klas i ozdobników w HTML. Do takich zadań CSS ma pseudo-klasy i pseudo-elementy.

Mohamed wskazuje na malowidła w świątyni: "Widzisz, jak kolory zmieniają się w zależności od światła? W CSS mamy pseudo-klasy i pseudo-elementy, które pozwalają zmieniać wygląd elementów w zależności od ich stanu lub dodawać dekoracje bez zmiany HTML!"

Pseudo-klasy - reagowanie na stan

Pseudo-klasy pozwalają stylować elementy w zależności od ich stanu lub pozycji w dokumencie. Zapisujemy je z jednym dwukropkiem :.

Stany interaktywne

Pierwsza grupa reaguje na to, co robi użytkownik: najeżdża kursorem, klika, przechodzi klawiszem Tab do pola formularza:

/* Odwiedzony link */
a:visited {
  color: #8B7355;
}

/* Gdy kursor jest nad elementem */
a:hover {
  color: gold;
  text-decoration: underline;
}

/* Gdy element jest aktywny (kliknięty) */
button:active {
  background-color: darkgoldenrod;
  transform: scale(0.95);
}

/* Gdy element ma fokus (np. po kliknięciu Tab) */
input:focus {
  border-color: gold;
  outline: 2px solid rgba(255, 215, 0, 0.5);
}

Kolejność ma znaczenie: a:visited stoi przed a:hover. Obie reguły są równie silne, więc wygrywa późniejsza - gdyby :visited stała niżej, odwiedzony link nie złociłby się po najechaniu. MDN zaleca kolejność :link, :visited, :hover, :active. Nie usuwaj też obrysu :focus bez innego wyraźnego stylu - korzystają z niego osoby poruszające się po stronie klawiaturą.

Pseudo-klasy strukturalne

Druga grupa pozwala wybierać elementy na podstawie ich pozycji w drzewie dokumentu - który jest pierwszy, który ostatni, a który co drugi:

/* Pierwszy element dziecko */
li:first-child {
  font-weight: bold;
  color: gold;
}

/* Ostatni element dziecko */
li:last-child {
  border-bottom: 2px solid gold;
}

/* Co drugi element (parzyste) */
tr:nth-child(even) {
  background-color: #f5f0e6;
}

/* Co drugi element (nieparzyste) */
tr:nth-child(odd) {
  background-color: #fff;
}

/* Co trzeci element */
li:nth-child(3n) {
  color: crimson;
}

/* Trzeci element od końca */
li:nth-last-child(3) {
  font-style: italic;
}

Elementy liczymy od 1, nie od 0, więc nth-child(3n) wybiera trzeci, szósty i dziewiąty element, a even i odd to parzyste i nieparzyste. Od najwcześniejszego kolejność brzmi: :first-child, :nth-child(2), :nth-child(3), a na końcu :last-child.

Nowoczesne pseudo-klasy

Trzecia grupa to nowsze narzędzia, które skracają długie selektory i pozwalają wybierać elementy na podstawie tego, co zawierają:

/* Negacja - wszystkie linki OPRÓCZ klasy .special */
a:not(.special) {
  color: #8B6914;
}

/* Grupowanie selektorów - :is() */
:is(h1, h2, h3):hover {
  color: gold;
}

/* :has() - selektor rodzica (najnowszy!) */
/* Styluj artykuł, KTÓRY ZAWIERA obrazek */
article:has(img) {
  border: 2px solid gold;
  padding: 20px;
}

/* Div, który zawiera pusty paragraf */
div:has(p:empty) {
  display: none;
}

Pseudo-klasa :not() odwraca warunek, :is() zbiera kilka selektorów w jeden, a :has() wybiera rodzica na podstawie jego zawartości - article:has(img) stylizuje artykuł, a nie obrazek. Główne przeglądarki obsługują :has() od końca 2023 roku.

Pseudo-elementy - dekoracje bez HTML

Pseudo-elementy pozwalają stylować części elementu lub dodawać treść dekoracyjną bez zmiany HTML. Zapisujemy je z dwoma dwukropkami ::. Przeglądarki rozumieją też stary zapis z jednym dwukropkiem, np. :before, ale polecam zawsze pisać ::, żeby odróżnić je od pseudo-klas.

::before i ::after

Dodają treść przed lub po zawartości elementu, wewnątrz niego. Wymagają właściwości content: bez niej pseudo-element w ogóle nie powstanie, nawet jeśli nadasz mu kolor i wymiary.

/* Dodaj hieroglif przed nagłówkiem */
h2::before {
  content: "𓂀 ";
  color: gold;
}

/* Dodaj strzałkę po linku */
a::after {
  content: " →";
  color: gold;
}

/* Dekoracyjna linia pod nagłówkiem */
h1::after {
  content: "";
  display: block;
  width: 100px;
  height: 3px;
  background: linear-gradient(to right, gold, transparent);
  margin-top: 10px;
}

W trzecim przykładzie content: "" to pusty napis, ale wystarczy, żeby pseudo-element powstał - resztę robią wymiary i gradient. Pełna reguła to selektor, pseudo-element i blok z content, np. h1::after { content: "→"; }. Tej treści nie ma w HTML, więc nie wpisuj tam niczego ważnego.

::placeholder i ::selection

Te dwa pseudo-elementy stylizują podpowiedź w pustym polu formularza i tekst zaznaczony myszką - fragmentów tych nie wskażesz żadnym znacznikiem.

/* Styl placeholdera w input */
input::placeholder {
  color: #c4a35a;
  font-style: italic;
}

/* Styl zaznaczonego tekstu */
p::selection {
  background-color: gold;
  color: #2c1810;
}

Placeholder znika, gdy użytkownik zaczyna pisać, więc nie zastępuje etykiety pola.

::first-line i ::first-letter

Ostatnia para działa na tekście akapitu - wybiera jego pierwszą linię albo pierwszą literę, jak ozdobny inicjał w rękopisie skryby.

/* Pierwsza litera paragrafu - efekt inicjału */
p::first-letter {
  font-size: 3em;
  float: left;
  color: gold;
  font-family: serif;
  line-height: 1;
  margin-right: 5px;
}

/* Pierwsza linia tekstu */
p::first-line {
  font-weight: bold;
  color: #8B6914;
}

Deklaracje float: left i duży font-size tworzą inicjał wysoki na kilka linii tekstu.

Praktyczne zastosowania

Teraz połączmy obie rodziny w prawdziwych komponentach.

Interaktywna lista z efektami hover

Pierwszy komponent to lista faraonów, której wiersze po najechaniu dostają tło i złotą lewą ramkę:

.pharaoh-list li {
  padding: 10px;
  transition: all 0.3s ease;
  border-left: 3px solid transparent;
}

.pharaoh-list li:hover {
  background-color: #f5f0e6;
  border-left-color: gold;
  padding-left: 20px;
}

.pharaoh-list li:nth-child(even) {
  background-color: #faf8f3;
}

.pharaoh-list li::before {
  content: "» ";
  color: gold;
}

Deklaracja transition sprawia, że zmiana jest płynna - przejścia poznasz w module o animacjach. Reguła ::before ma na razie pusty content, więc nic nie wyświetla - w ćwiczeniu wpiszesz tam strzałkę.

Przyciski z pseudo-elementami

Drugi komponent to przycisk, po którym przy najechaniu przesuwa się pas światła, jak promień słońca po złotej masce:

.btn-egyptian {
  position: relative;
  padding: 12px 24px;
  background: #8B6914;
  color: white;
  border: none;
  overflow: hidden;
}

.btn-egyptian::before {
  content: "";
  position: absolute;
  top: 0;
  left: -100%;
  width: 100%;
  height: 100%;
  background: linear-gradient(
    90deg, transparent, rgba(255,215,0,0.3), transparent
  );
  transition: left 0.5s;
}

.btn-egyptian:hover::before {
  left: 100%;
}

Pseudo-element ::before to pas gradientu ukryty poza przyciskiem (left: -100%), który po najechaniu przesuwa się na drugą stronę. Zwróć uwagę na zapis :hover::before - najpierw pseudo-klasa, potem pseudo-element.

Tooltips z CSS

Trzeci komponent to dymek z podpowiedzią, którego tekst funkcja attr() pobiera z atrybutu data-tooltip w HTML:

.tooltip {
  position: relative;
}

.tooltip::after {
  content: attr(data-tooltip);
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  background: #2c1810;
  color: gold;
  padding: 5px 10px;
  border-radius: 4px;
  font-size: 14px;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s;
}

.tooltip:hover::after {
  opacity: 1;
}

Dymek jest niewidoczny (opacity: 0) i pojawia się płynnie po najechaniu, a pointer-events: none sprawia, że nie przechwytuje kliknięć.

Debugowanie w DevTools

Gdy styl nie działa, nie zgaduj. Kliknij element prawym przyciskiem myszy i wybierz Zbadaj, znajdź w panelu Styles reguły, które go dotyczą, porównaj specyficzność selektorów i popraw wartość w inspektorze. Przycisk :hov wymusza stan :hover bez ruszania myszką. Działającą poprawkę przenieś do pliku CSS, bo zmiany w inspektorze znikają po odświeżeniu.

Mohamed podsumowuje: "Pseudo-klasy reagują na stan elementu, pseudo-elementy dodają dekoracje. Razem tworzą dynamiczne interfejsy bez dodatkowego HTML-a!"

W edytorze poniżej wszystkie te techniki działają razem - najedź na imiona faraonów i kliknij w pola formularza:

Kod do tej lekcji: index.html
<!DOCTYPE html>
<html lang="pl">
<head>
  <meta charset="UTF-8">
  <title>Pseudo-klasy i pseudo-elementy</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <h1>Faraonowie Egiptu</h1>

  <ul class="pharaoh-list">
    <li data-tooltip="2589-2566 p.n.e.">Cheops (Chufu)</li>
    <li data-tooltip="1332-1323 p.n.e.">Tutanchamon</li>
    <li data-tooltip="1279-1213 p.n.e.">Ramzes II</li>
    <li data-tooltip="51-30 p.n.e.">Kleopatra VII</li>
    <li data-tooltip="1479-1458 p.n.e.">Hatszepsut</li>
  </ul>

  <h2>Kontakt z muzeum</h2>
  <form>
    <label for="name">Twoje imię</label>
    <input type="text" id="name" placeholder="Twoje imię...">
    <label for="email">Twój e-mail</label>
    <input type="email" id="email" placeholder="Twój email...">
    <button class="btn-egyptian">Wyślij wiadomość</button>
  </form>

  <article>
    <p>Starożytny Egipt to jedna z najstarszych cywilizacji świata. Przez tysiące lat Egipcjanie budowali monumentalne budowle, rozwijali system pisma i tworzyli zaawansowaną kulturę, która fascynuje nas do dziś.</p>
  </article>
</body>
</html>

Pamiętaj: pseudo-klasa z jednym dwukropkiem reaguje na stan elementu, a pseudo-element z dwoma dwukropkami dodaje mu dekorację - jak światło zmieniające barwy malowideł i ozdobny inicjał skryby.

Hasła z dokumentacji w tej lekcji

Widzisz błąd w tej lekcji?

Sprawdź się

Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.

  1. 1. Która pseudo-klasa pozwala stylować element, gdy kursor myszy znajduje się nad nim?

  2. 2. Co jest wymagane, aby pseudo-element ::before lub ::after był widoczny?

To 2 z 3 pytań do tej lekcji. Pozostałe rozwiążesz w grze.

Zadania praktyczne w grze

  • Edytor kodu

    Odkomentuj i uzupełnij reguły CSS: hover, first-child, nth-child(even), ::before, :focus, ::placeholder, button:hover

  • Układanie w poziomie

    Ułóż elementy, aby stworzyć poprawną regułę CSS z pseudo-elementem ::after:

  • Klikanie w kolejności

    Ułóż selektory :nth-child od wybierającego najwcześniejsze do najpóźniejszych elementów:

  • Edytor kodu

    Odkomentuj i uzupełnij reguły CSS z pseudo-elementami: ::before na h1 i h2, ::after jako dekoracyjna linia, ::first-letter jako inicjał, ::selection

  • Układanie w pionie

    Ułóż kroki debugowania problemu ze stylami CSS:

  • Układanie w pionie

    Ułóż kroki rozwiązywania konfliktu stylów CSS (gdy element ma niespodziewany wygląd):

  • Edytor kodu

    Napisz stronę internetową o egipskich bogach. Użyj CSS do stylizacji: kolorów, czcionek, box model, trybów display (block, inline, inline-block) i selektorów potomków.

Przydatne artykuły