Lekcja 30
Kaskada, specyficzność i @layer
CSS jest kaskadowy: wiele reguł może dotyczyć tego samego elementu, a przeglądarka musi zdecydować, która deklaracja wygra. W tej lekcji uporządkujesz mentalny model kaskady i poznasz @layer jako narzędzie do kontroli kolejności stylów w większym projekcie.
Cele lekcji
Po ukończeniu tej lekcji będziesz umieć:
- wyjaśnić, czym jest kaskada CSS,
- ocenić podstawową specyficzność selektorów,
- zrozumieć rolę kolejności reguł w arkuszu,
- unikać eskalacji przez
!important, - rozpoznać wpływ stylów inline,
- używać
@layerdo porządkowania resetu, baz, komponentów i utilities.
Kontekst praktyczny
Problemy z kaskadą zaczynają się wtedy, gdy komponent trzeba nadpisać coraz mocniejszym selektorem. Najpierw pojawia się .card .title, potem .page .card .title, a na końcu !important. To zwykle sygnał, że projekt potrzebuje lepszego porządku warstw i niższej specyficzności.
Czym jest kaskada
Kaskada to zestaw zasad, które decydują, która deklaracja CSS zostanie zastosowana. Znaczenie mają między innymi: źródło stylu, warstwa, specyficzność selektora, kolejność w arkuszu oraz !important.
.button {
background: #2563eb;
}
.button {
background: #16a34a;
}
Jeżeli dwie reguły mają tę samą siłę, wygrywa deklaracja zapisana później. W przykładzie przycisk dostanie zielone tło.
Specyficzność
Specyficzność określa, jak mocny jest selektor. ID jest mocniejsze niż klasa, a klasa jest mocniejsza niż selektor elementu. Im bardziej rozbudowany selektor, tym trudniej go później nadpisać.
button {
color: #475569;
}
.button {
color: #2563eb;
}
#primary-action {
color: #dc2626;
}
W tym zestawie selektor ID wygra, nawet jeśli znajduje się wcześniej niż klasa. Dlatego ID rzadko jest dobrym wyborem do codziennego stylowania komponentów.
Kolejność źródła
Kiedy specyficzność jest taka sama, wygrywa reguła późniejsza. To prosty mechanizm, ale w dużym projekcie łatwo go zepsuć przez przypadkowe importy albo chaotyczną kolejność plików.
/* components.css */
.alert {
border-color: #bfdbfe;
}
/* utilities.css loaded later */
.alert {
border-color: #fca5a5;
}
Jeśli utilities mają być łatwe do nadpisywania komponentów, powinny być ładowane później albo umieszczone w późniejszej warstwie.
Important i inline
!important zmienia normalną kolejność rozstrzygania deklaracji. Style inline są bardzo mocne i zwykle powinny być używane ostrożnie, szczególnie gdy później chcesz kontrolować wygląd z arkusza CSS.
.badge {
color: #2563eb !important;
}
<span class="badge" style="color: #dc2626;">
Status
</span>
!important bywa potrzebne w klasach utility albo wyjątkach dostępnościowych, ale używane bez kontroli prowadzi do wojny deklaracji.
Podstawy @layer
@layer pozwala jawnie określić kolejność grup stylów. Dzięki temu reset, style bazowe, komponenty i utility mogą mieć przewidywalną hierarchię bez podbijania specyficzności.
@layer reset, base, components, utilities;
@layer components {
.button {
padding: .75rem 1rem;
}
}
Kolejność podana w pierwszej deklaracji jest ważna. Warstwa zapisana później w tej liście ma większy priorytet niż wcześniejsza.
Kolejność warstw
Warstwy pomagają uniknąć selektorów typu .page .section .card .button. Utility może wygrać z komponentem, bo jest w późniejszej warstwie, nawet jeśli ma prostszy selektor.
@layer components {
.button {
background: #2563eb;
}
}
@layer utilities {
.u-bg-success {
background: #16a34a;
}
}
Jeśli utilities jest późniejszą warstwą niż components, klasa .u-bg-success może wygrać bez selektora o większej specyficzności.
Demo kaskady
Demo pokazuje różnicę między chaotycznym nadpisywaniem i uporządkowanymi warstwami. W obu przypadkach efekt może wyglądać podobnie, ale koszt utrzymania jest zupełnie inny.
Rosnąca specyficzność
Każde nadpisanie wymaga mocniejszego selektora albo kolejnego wyjątku.
- element
button - klasa
.button - łańcuch
.page .card .button
Jawna kolejność
Proste selektory działają, bo kolejność warstw jest częścią architektury.
- reset
@layer reset - komponent
@layer components - utility
@layer utilities
Najczęstsze błędy początkujących
- Dodawanie coraz dłuższych selektorów zamiast zmniejszenia specyficzności.
- Nadużywanie ID do stylowania komponentów.
- Używanie
!importantjako pierwszego sposobu naprawy. - Ładowanie plików CSS w przypadkowej kolejności.
- Mieszanie resetu, komponentów i utilities w jednej nieuporządkowanej warstwie.
- Zakładanie, że
@layerzastępuje dobre nazwy klas i czytelną strukturę plików.
Mini zadanie
Uporządkuj style dla przycisku w małym systemie UI.
- Zdefiniuj kolejność warstw:
reset,base,components,utilities. - Umieść bazowy styl
.buttonw warstwiecomponents. - Dodaj utility
.u-bg-successw warstwieutilities. - Sprawdź, czy utility wygrywa bez
!important. - Usuń zbyt długi selektor, jeśli możesz zastąpić go warstwą albo prostszą klasą.
Checklista
- Rozumiem, że kaskada decyduje, która deklaracja CSS wygrywa.
- Potrafię porównać specyficzność elementu, klasy i ID.
- Wiem, kiedy kolejność źródła ma znaczenie.
- Używam
!importantświadomie i rzadko. - Potrafię zaplanować podstawową kolejność warstw przez
@layer. - Nie podbijam specyficzności, gdy problemem jest organizacja arkusza.
Podsumowanie lekcji
Kaskada nie jest błędem CSS, tylko jego podstawowym mechanizmem. Specyficzność, kolejność źródła, !important i @layer trzeba rozumieć jako narzędzia kontroli. Dobrze zaprojektowane warstwy pozwalają pisać prostsze selektory i ograniczają chaos w większym projekcie.
Kolejny krok roadmapy to reset, normalize i style bazowe.
Przejdź do Lekcji 31