☰ menu
Pavel Satrapa

Pokročilé vztahy mezi prvky

Selektory v CSS umožňují vyjádřit i některé rafinovanější vztahy mezi prvky. Tyto selektory trpěly slabší podporou v klientech, ovšem moderní generace webových prohlížečů je umí. V současnosti není důvod se jich obávat.

Dítě (>)

Trochu se podobá selektoru potomka. Tentokrát ovšem požaduje, aby druhý z uvedených prvků byl dítětem (čili přímým potomkem, bez jakýchkoli prvků v hierarchii mezi nimi) prvního. Zapisuje se pomocí znaku „>“ mezi příslušnými prvky. Například

h1 > em { color: red; }

bude uplatněno na <em> v nadpisu:

<h1>Příkaz <em>delete</em></h1>

nikoli však na

<h1>Příkaz <a id="delete"><em>delete</em></a></h1>

kde vadí <a> nacházející se v hierarchii mezi nimi.

Následník (+, ~)

Zapíšete-li v selektoru mezi dvojici prvků „+“, požadujete, aby druhý byl následníkem prvního. To znamená, že oba mají stejného rodiče a ve zdrojovém kódu se nacházejí bezprostředně za sebou. Pravidlo se vztahuje jen na druhý prvek.

Například pravidlu

h2 + p { color: gray; }

vyhoví jen takové <p>, jež následuje ihned za nadpisem <h2>. Například první ze dvou odstavců v tomto kódu bude šedý:

<h2>Instalace</h2>

<p>V této části popíšeme instalaci programu.</p>

<p>Program ke své činnosti využívá...</p>

Existuje také volnější verze tohoto selektoru, zapisovaná znakem „vlnka“ (~). Platí pro všechny sourozence prvního prvku, kteří se ve zdrojovém kódu nacházejí za ním. Například toto pravidlo

h2 ~ p { color: blue; }

obarví všechny odstavce následující za <h2> modře. Mohou mezi ně být vloženy i jiné prvky (např. <h3> nebo <ul>), ale pokud se kdekoli před ním ve zdrojovém kódu nachází <h2> se stejným rodičem, bude odstavec modrý.

Obsahuje (:has())

Většina selektorů, které se zabývají vztahy mezi prvky, se ohlíží směrem zpět k předkům nebo předchůdcům prvku, kterého se týkají. Lze nastavit vlastnosti prvku, který se vyskytuje uvnitř jiného, následuje za jiným a podobně. Velmi dlouho trvalo, než se v CSS objevil selektor, který se dívá na potomky.

Jedná se o selektor :has(potomci). Vyhoví mu prvek, pro který existuje alespoň jeden prvek vyhovující vnořenému selektoru potomci. Řekněme, že máte na stránce bloky a chcete barevným pozadím odlišit ty z nich, které v sobě obsahují obrázek:

.blok {
    background-color: #eee;
}

.blok:has(img) {
    background-color: #f2d399;
}

Druhému selektoru vyhoví takové prvky s třídou blok, které v sobě obsahují prvek <img>, libovolně hluboko vnořený. Pokud byste chtěli, aby vyhověly jen ty bloky, kde obrázek je dítětem, tedy přímým potomkem bloku, bylo by třeba druhý selektor upravit na:

.blok:has(>img) {
    background-color: #f2d399;
}

Selektor uvnitř :has() se vyhodnocuje v kontextu prvku, který vyhověl selektoru, k němuž je připojen. V našem příkladu se tedy hledá mezi potomky jednotlivých prvků, které mají přiřazenu třídu blok.

Uvnitř :has() může být několik selektorů, oddělujte je čárkami. Bude splněn, pokud alespoň pro jeden existuje vyhovující prvek. Stejně se chová, když k prvku připojíte několik :has(). Obarvení bloku, který obsahuje alespoň jeden nadpis <h2> nebo <h3>, by zajistila některá z těchto deklarací:

.blok:has(h2, h3) {
    background-color: #f2d399;
}

.blok:has(h2):has(h3) {
    background-color: #f2d399;
}

Selektory uvnitř :has() jsou mírně omezeny. Nelze v nich používat další :has(), ani pseudoprvky. Většinu selektorových konstrukcí ale používat můžete. Běžným požadavkem například může být odstranit okraj pod nadpisem <h2>, pokud je bezprostředně následován nadpisem <h3>:

h2:has(+ h3) {
    margin-bottom: 0;
}

Nebo řekněme, že seznam s odrážkami <ul> má vypadat jinak, pokud obsahuje alespoň 5 odrážek (tedy existuje v něm páté dítě typu <li>):

ul:has(>li:nth-of-type(5)) {
    ...
}