Używaj zapytań o style (@container style()), aby aktywować odmiany kontekstowe bez kodowania na stałe tego, co generuje dany kontekst lub na niego reaguje. Zmniejsza to powiązanie systemu projektowania i poprawia rozszerzalność oraz hermetyzację komponentów.
Na przykład reguła section.featured { --surface: featured } może oznaczać kontekst, a strona docelowa może też domyślnie używać go za pomocą main { --surface: featured }. Komponenty mogą reagować na --surface: featured: na karcie pojawia się plakietka promocyjna, przycisk domyślnie zmienia się na wypełniony itd.
Zapytania o style pozwalają obu stronom zachować niezależność: polecane powierzchnie nigdy nie nazywają elementów, które się do nich dostosowują, a komponenty nigdy nie sprawdzają, co wygenerowało kontekst. Każdą stronę można rozszerzać niezależnie – nowe komponenty, nowe polecane platformy – bez wpływu na drugą stronę. Selektory potomne (np. .featured .button) wymuszają odwrotne działanie: selektor musi kodować obie strony relacji i musi się zmieniać, gdy zmienia się dowolna z nich.
Kiedy korzystać z tego przewodnika
Ten przewodnik dotyczy zmian behawioralnych: komponent decyduje, co renderować, jak się ułożyć lub który wariant zaprezentować w odpowiedzi na kontekst – ukrywa lub pokazuje plakietkę, zmienia kierunek układu lub zamienia wariant przycisku.
Jeśli potrzebujesz zmian na poziomie tokenów – trybów gęstości, motywów lub innych tokenów wyższego rzędu, które jednolicie zmieniają wartości, takie jak dopełnienie i kolor, w wielu komponentach – zapoznaj się z artykułem Reaktywność tokenów projektowych.
Wybór odpowiedniego narzędzia
Zapytanie o styl warto zastosować, gdy obie strony relacji kontekstowej mogą zmieniać się niezależnie – nowe elementy mogą zacząć tworzyć kontekst lub nowe komponenty mogą zacząć na niego reagować. Pośredniość opłaca się pod względem rozszerzalności i enkapsulacji, a zapytania o styl przekraczają granice modelu Shadow DOM, czego nie mogą zrobić selektory potomne. Jeśli nie potrzebujesz takiej elastyczności, wybierz prostsze narzędzie:
- Selektory potomne (
.toolbar .button): stała, jednorazowa relacja, której nie można ponownie wykorzystać ani rozszerzyć. Zastosuj zasadę YAGNI – nie dodawaj pośrednictwa, którego nie będziesz używać. - Zapytania o rozmiar (
@container (min-width: …)): zmiany układu i gęstości wynikające z dostępnego miejsca, a nie stanu semantycznego. - Zapytania o styl (
@container style(…)): stan semantyczny – co komponent powinien renderować, rozmieszczać lub prezentować w danym kontekście.
Dyrektywy dotyczące implementacji
- Zdefiniuj flagę kontekstu semantycznego za pomocą właściwości niestandardowej CSS w kontenerze.
- NIE ustawiaj właściwości
container-typew przypadku zapytań o style. Odpytują one odziedziczone właściwości niestandardowe najbliższego elementu nadrzędnego i nie wymagają wyraźnego kontekstu kontenera. - OBOWIĄZKOWO: użyj
@container style(--property: value), aby zastosować style warunkowe do elementów podrzędnych. Zapytania o style nie mogą pasować do elementu, dla którego ustawiono właściwość, a jedynie do jego elementów podrzędnych. - ZALECAMY preferowanie zapytań o styl nad selektorami potomnymi, gdy relacja musi być rozszerzalna lub przekraczać granice komponentu/shadow DOM (patrz Wybór odpowiedniego narzędzia powyżej) – ale zachowaj selektory potomne w przypadku stałych, jednorazowych relacji, w których pośrednictwo nic nie daje.
Przykład wdrożenia
/* 1. Set the context on a layout container */
.featured {
--surface: featured; /* Semantic context flag for children */
}
/* 2. Component reacts to inherited flag */
.button {
/* Default: Outlined informational style */
background: transparent;
border: 1px solid currentColor;
}
.badge {
/* Default: Hidden — only revealed in featured surfaces */
display: none;
}
@container style(--surface: featured) {
.button {
/* Automatic switch to Filled promotional style */
background: var(--brand-accent);
color: white;
border: none;
}
.badge {
/* Reveal decorative elements only in featured context */
display: block;
}
}
Strategie zastępcze
Dopóki zapytania o styl kontenera nie będą powszechnie dostępne, nakładaj je jako progresywne ulepszanie: dostarczaj domyślne zapytanie oparte na selektorze, które działa wszędzie, i pozwól, aby zapytanie o styl je zastępowało, gdy jest obsługiwane. Użyj :where() w selektorze kontekstu, aby zapytanie o styl (ta sama specyficzność, później w kolejności źródłowej) wygrało automatycznie.
/* Default styles — work everywhere */
.button {
background: transparent;
border: 1px solid currentColor;
}
.badge {
display: none;
}
/* Selector-based contextual styles — broad browser support */
:where(.featured) .button {
background: var(--brand-accent);
color: white;
border: none;
}
:where(.featured) .badge {
display: block;
}
/* Progressive enhancement: style queries override when supported */
@container style(--surface: featured) {
.button {
background: var(--brand-accent);
color: white;
border: none;
}
.badge {
display: block;
}
}
Selektor zastępczy wiąże styl kontekstowy z nazwą klasy, co łączy komponent z jego miejscem w DOM. Gdy zapytania o style będą powszechnie obsługiwane, regułę :where() będzie można usunąć.