Koszt selektorów i best practices
Koszt selektorów i best practices
W CSS nie wszystkie selektory są sobie równe. Choć efekt wizualny może być identyczny, niektóre selektory są znacznie „droższe” dla przeglądarki pod względem wydajności. W tej lekcji nauczysz się, jak świadomie tworzyć selektory, które są szybkie, przewidywalne i łatwe w utrzymaniu.
Jak przeglądarka „czyta” CSS?
Pod maską przeglądarka przetwarza CSS w trzech etapach:
- Parsowanie selektorów – przeglądarka rozbija CSS na reguły i sprawdza, które z nich pasują do elementów DOM.
- Matchowanie – selektory są porównywane z drzewem DOM – od prawej do lewej (ważne!).
- Renderowanie – po ustaleniu stylów, przeglądarka rysuje efekt na ekranie.
Im bardziej złożony selektor, tym więcej pracy przeglądarki.
Przykład: selektor prosty vs złożony
/* Prosty */
.button {
background-color: blue;
}
/* Złożony */
section > div.container ul li a.button:hover {
background-color: blue;
}
Efekt ten sam, ale przeglądarka w drugim przypadku musi wykonać więcej kroków, aby „dojść” do odpowiedniego elementu.
Najdroższe selektory (wydajnościowo)
*– gwiazdka (selektor uniwersalny)li a– selektory potomków bez klasydiv > a.button:hover– złożone z potomkami, pseudoklasami[attribute=value]– selektory atrybutów:not(.klasa),:nth-child– pseudoklasy z logiką
Uwaga: różnice w wydajności są marginalne przy małych projektach, ale w dużych aplikacjach SPA – mają znaczenie.
Best practices – dobre praktyki projektowania selektorów
- Unikaj zbyt ogólnych selektorów – np.
*,div p,ul li a - Preferuj klasy zamiast selektorów tagów –
.card-titlezamiasth3.card-title - Nie zagnieżdżaj zbyt głęboko – maksymalnie 2–3 poziomy, np.
.section .card .title - Unikaj selektorów ID – mają najwyższą specyficzność, trudne do nadpisywania
- Stosuj zasadę: selektor = nazwa roli komponentu – np.
.form__label
Specyficzność – co wpływa na to, kto „wygrywa”?
Przeglądarka stosuje reguły na podstawie tzw. specyficzności. W skrócie:
#id= 100 punktów.class,[attr],:hover= 10 punktówdiv,h1,p= 1 punkt
Im wyższa specyficzność, tym trudniej coś nadpisać. Dlatego np. #header h1 przeważy nad .header__title.
Złe praktyki (których warto unikać)
/* Zła praktyka: selektor z ID + tag + klasa + pseudoklasa */
#main-content div.card .title:hover {
color: red;
}
To trudne do debugowania, trudne do nadpisania, kosztowne przy renderze. Lepiej:
.card__title:hover {
color: red;
}
Jakie selektory są „tanie” i wydajne?
- Proste klasy komponentów:
.button,.alert,.nav__item - Klasy z BEM:
.form__input,.card--highlighted - Klasy narzędziowe:
.text-center,.mb-2 - Ograniczona głębokość: maks. 2–3 selektory w łańcuchu
Ćwiczenie
Zidentyfikuj 3 reguły CSS w swoim projekcie, które mają selektory z ponad 3 poziomami zagnieżdżenia lub używają ID. Przepisz je w stylu komponentowym (np. BEM) tak, by:
- każdy komponent miał unikalną klasę,
- selekcja była maksymalnie uproszczona,
- kod był łatwy do nadpisania i rozbudowy.
Wniosek
CSS jest szybki – ale tylko wtedy, gdy Ty mu na to pozwolisz. Zbyt skomplikowane selektory mogą powodować trudne do wykrycia problemy wydajnościowe. Prosta zasada: preferuj klasy, trzymaj się płytkich struktur, nie buduj selektorów jak drzewo genealogiczne. To czyni Twój kod przewidywalnym, skalowalnym i przyjaznym dla innych frontendowców.
