Selektor :has() a vrstvy kaskády
Dvě novinky, které spolu na první pohled nesouvisejí, ale v praxi se potkávají: jedna se dostane tam, kam to dřív nešlo, druhá pak uklidí nepořádek, který tím může vzniknout ve specificitě.
Rodičovský selektor
Dlouho platilo, že CSS umí hledat jen směrem dolů – od rodiče k potomkovi.
Pseudotřída :has() to obrací:
/* karta, ve které je obrázek, dostane jiné rozvržení */
.card:has(img) {
grid-template-columns: 150px 1fr;
}
/* políčko formuláře, ve kterém je neplatná hodnota */
.field:has(input:invalid) {
border-color: var(--color-danger);
}Podmínka pořád hledá dolů, obarví se ale prvek, na kterém stojí. Poprvé se tak dá v CSS říct „udělej něco s prvkem, který uvnitř sebe něco má“ – a spousta věcí, kvůli kterým se dřív sahalo po JavaScriptu, se scvrkne na jeden selektor.
:has() si bere specificitu svého nejsilnějšího argumentu. Zápis
.card:has(#promo) je proto stejně silný jako selektor na id a přebije skoro
všechno ostatní. Tohle je přesně ten druh překvapení, na který se hodí vrstvy
z druhé půlky kapitoly.
Vrstvy kaskády
Vrstva je pojmenovaná přihrádka na pravidla. Jejich pořadí se určí tam, kde se poprvé vyjmenují, a od té chvíle platí, že pozdější vrstva vyhrává bez ohledu na specificitu:
@layer reset, components, utilities;
@layer components {
.card .title { color: var(--color-text); }
}
@layer utilities {
.text-muted { color: var(--color-text-muted); }
}Selektor .text-muted má specificitu nižší než .card .title, a přesto vyhraje.
Uvnitř jedné vrstvy se pořadí řeší po staru specificitou; mezi vrstvami
rozhoduje jejich pořadí. Je to náhrada za !important, jenom se s ní dá žít.
Pravidla, která nejsou v žádné vrstvě, jsou silnější než všechno ve vrstvách. Vypadá to obráceně, než by člověk čekal, ale dává to smysl: nezařazený kód stojí až nad poslední přihrádkou.
V praxi se vrstvy nasazují hlavně tam, kde se potkává cizí knihovna s vlastním
kódem. Knihovna dostane vrstvu pod tou naší a rázem přestane překvapovat, aniž
by kdokoli musel psát !important nebo přebíjet selektory delšími selektory.
Zjistěte v dokumentaci MDN, co udělá !important uvnitř vrstvy. Pořadí vrstev
se pro taková pravidla obrací a stojí za to vědět proč.