Lekcja 36
CSS nesting i nowoczesna składnia
CSS nesting pozwala grupować reguły związane z jednym komponentem bez powtarzania pełnego selektora w każdej linijce. To wygodne narzędzie, ale wymaga dyscypliny: zagnieżdżenie ma poprawiać czytelność, a nie budować trudne do nadpisania łańcuchy selektorów.
Cele lekcji
Po ukończeniu tej lekcji będziesz umieć:
- wyjaśnić, czym natywny CSS nesting różni się od zwykłego powtarzania selektorów,
- użyć selektora rodzica
&dla stanów, wariantów i klas łączonych, - rozpoznać różnice między nestingiem w CSS i preprocesorach typu Sass,
- bezpiecznie używać zagnieżdżonych
@media,@supportsi@containerw architekturze opartej o warstwy, - kontrolować specyficzność i głębokość zagnieżdżeń,
- decydować, kiedy nesting poprawia utrzymanie kodu, a kiedy lepszy jest płaski selektor.
Kontekst praktyczny
W większym arkuszu style komponentu często są rozproszone: baza, elementy, stany, media queries i warianty bywają oddzielone od siebie wieloma liniami. Nesting pomaga zebrać powiązane reguły bliżej siebie, zwłaszcza w komponentach takich jak karta, alert, przycisk czy panel dashboardu.
Czym jest CSS nesting
Nesting pozwala umieścić jedną regułę stylu wewnątrz drugiej. Wewnętrzny selektor jest interpretowany względem selektora zewnętrznego. Dzięki temu możesz utrzymać reguły komponentu w jednym bloku.
/* Bez nestingu */
.notice {
padding: 1rem;
}
.notice h3 {
margin: 0;
}
/* Z nestingiem */
.notice {
padding: 1rem;
h3 {
margin: 0;
}
}
Taki zapis nie oznacza, że komponent staje się izolowany jak Shadow DOM. To nadal normalny CSS, z normalną kaskadą, specyficznością i kolejnością źródła.
Selektor rodzica &
& reprezentuje selektor zewnętrzny. Jest potrzebny wtedy, gdy chcesz połączyć selektor bez spacji, na przykład przy pseudoklasie, modyfikatorze albo klasie stanu.
.button {
background: #2563eb;
&:hover {
background: #1d4ed8;
}
&.is-loading {
cursor: wait;
}
}
Bez & zapis :hover wewnątrz .button mógłby zostać potraktowany jak potomek, czyli coś innego niż .button:hover. Dlatego przy stanach komponentu używaj &:hover, &:focus-visible i &.is-active.
Stany komponentu
Najbardziej czytelny przypadek nestingu to komponent ze stanami. Baza zostaje na górze, a pod nią znajdują się stany interakcji i warianty semantyczne.
.lesson-card {
border: 1px solid var(--color-border);
border-radius: .75rem;
padding: 1rem;
&:hover {
border-color: #2563eb;
}
&:focus-within {
outline: 3px solid #93c5fd;
outline-offset: 3px;
}
&.lesson-card--featured {
background: #eff6ff;
}
}
Uwaga: natywny CSS nie działa jak każde rozszerzenie Sass. Dla modyfikatora tego samego elementu użyj &.lesson-card--featured albo trzymaj wariant jako osobną regułę, jeśli zespół nie ma jasnej konwencji.
Zagnieżdżone at-rules
Nesting może grupować także reguły warunkowe przy komponencie. To pomaga utrzymać breakpoint, container query albo feature query blisko komponentu, którego dotyczą.
.profile-card {
display: grid;
gap: 1rem;
@media (min-width: 48rem) {
grid-template-columns: 8rem 1fr;
}
@supports (container-type: inline-size) {
container-type: inline-size;
}
}
To jest wygodne, ale nie zawsze najlepsze. Jeśli wszystkie breakpointy projektu trzymacie w osobnej sekcji pliku, trzymaj się konwencji projektu. Nesting nie powinien rozbijać architektury CSS.
Sass vs natywny CSS
Natywny CSS nesting nie jest prostym kopiowaniem możliwości Sass. CSS nie skleja selektorów jako tekstu. To ważne przy nazwach BEM-like i skrótach typu &__title albo &--active.
/* Wzorzec z Sass - nie wklejaj bez sprawdzenia do natywnego CSS */
.card {
&__title {
margin: 0;
}
}
/* Czytelniejszy wariant w natywnym CSS */
.card {
.card__title {
margin: 0;
}
&.card--featured {
border-color: #2563eb;
}
}
W realnym projekcie wybierz zapis, który jest zrozumiały dla zespołu i zgodny z narzędziami. Jeśli nie używasz build stepu, testuj składnię bezpośrednio w docelowych przeglądarkach.
Specyficzność i głębokość
Nesting nie powinien być wymówką do budowania selektorów na cztery poziomy. Im głębszy selektor, tym trudniej przewidzieć, co wygra w kaskadzie i jak napisać rozsądny wariant komponentu.
/* Zbyt głęboko */
.dashboard {
.panel {
.card {
.card__title {
color: #0f172a;
}
}
}
}
/* Lepiej: komponent jako granica */
.card {
.card__title {
color: #0f172a;
}
}
Dobra praktyka: jeden poziom dla elementów, jeden poziom dla stanów, a zagnieżdżone at-rules tylko wtedy, gdy realnie poprawiają czytelność.
Demo CSS nesting
Demo pokazuje ten sam komponent zapisany w wersji płaskiej i zagnieżdżonej. Efekt wizualny jest taki sam, ale wersja z nestingiem grupuje bazę, elementy i stany bliżej siebie.
Selektory rozproszone
Każda reguła powtarza pełny selektor komponentu. To bywa czytelne, ale przy wielu stanach robi się długie.
.course-card.course-card:hover.course-card .course-card__meta
Reguły przy komponencie
Baza, elementy i stany są zgrupowane w jednym bloku, ale nadal trzeba pilnować głębokości i specyficzności.
.course-card { ... }&:hover { ... }.course-card__meta { ... }
Najczęstsze błędy początkujących
- Przenoszenie nawyków z Sass bez sprawdzenia, czy dana forma jest poprawna w natywnym CSS.
- Tworzenie głębokich selektorów typu
.page .section .card .titletylko dlatego, że nesting to ułatwia. - Zapominanie o
&przy pseudoklasach i klasach stanu. - Ukrywanie breakpointów w wielu komponentach bez spójnej konwencji w projekcie.
- Mieszanie stylów layoutu strony i stylów komponentu w jednym zagnieżdżeniu.
- Zakładanie, że nesting automatycznie obniża specyficzność albo izoluje komponent.
Mini zadanie
Przepisz prosty komponent karty kursu z płaskiego CSS na nesting.
- Zostaw bazę komponentu w selektorze
.course-card. - Zagnieżdź style dla
.course-card__title,.course-card__metai.course-card__actions. - Dodaj stany
&:hoveri&:focus-within. - Dodaj wariant wyróżniony jako osobną, czytelną regułę lub przez
&.course-card--featured. - Dodaj zagnieżdżony
@media (min-width: 48rem), który zmienia układ karty. - Po rozwinięciu selektorów sprawdź, czy żaden nie ma więcej niż dwóch poziomów zależności.
Checklista
- Rozumiem, że CSS nesting grupuje reguły, ale nie izoluje komponentu.
- Potrafię użyć
&przy:hover,:focus-visiblei klasie stanu. - Wiem, kiedy lepiej zostawić selektor płaski.
- Nie buduję zagnieżdżeń głębszych niż realnie potrzebne.
- Rozróżniam natywny CSS nesting od wygód składniowych Sass.
- Potrafię umieścić
@medialub@supportsprzy komponencie bez łamania architektury pliku.
Podsumowanie lekcji
CSS nesting porządkuje kod komponentu, gdy używasz go z umiarem. Największa wartość pojawia się przy stanach, wariantach i regułach warunkowych blisko komponentu. Największe ryzyko to ukryta specyficzność i głębokie zależności, które później trudno utrzymać.
Kolejny krok roadmapy to tryby kolorów, zmienne motywu i dark mode.
Przejdź do Lekcji 37