Přejít k navigační liště

Zdroják » Webdesign » Relační selektor :has – zdaleka ne jen selektor rodiče

Relační selektor :has – zdaleka ne jen selektor rodiče

Články Webdesign

Funkční selektor :has() můžeme použít jako selektor rodiče, tedy vybrat rodičovské prvky, obsahující potomky určitého typu. Podívejme se na něj detailně.

Text vyšel původně na webu autora.

:has() je funkční selektor, který můžeme mimo jiné použít jako selektor rodiče, tedy vybrat rodičovské prvky, obsahující potomky určitého typu:

a:has(img) { }

Tento selektor cílí na všechny odkazy (a), které mají v DOMu jako potomka obrázek (img).

Je to selektor rodiče. Ale taky nemusí být.

Selektor :has je podporován v Safari, a to od verze 15.4 z března 2022. Fanfáry prosím!

Chrome oznámil, že od verze 101, takže v nejbližším měsíci, bude selektor podporovat zkušebně s možností zapnout jej pod nastavením vlaječek (flags).

Nejen selektor rodiče

Selektor :has je součástí návrhu specifikace W3C Selectors Level 4. Vzbudil velkou pozornost, protože jednou z možností jeho použití je právě selektor rodiče, což je v CSS už asi dvacet let něco jako banány za komunistů. Lidé to strašně moc chtějí, stáli by na to fronty, ono se to občas někde objeví, ale zpravidla je to planý poplach.

Jenže :has ve skutečnosti selektor rodiče není. Doslovně, přesně podle specifikace, jde o relační pseudotřídu (Relational Pseudo-class). Relační proto, že do závorek můžete napsat jakýkoliv relativní selektor, se vztahem k selektoru před dvojtečkou:

/* Vybere <a>, jejichž přímým potomkem je <img>: */
a:has(> img) { }

/* Vybere všechny <section>, které obsahují <h1> nebo <h2>: */
section:has(h1, h2) { }

/* Vybere všechny <img>, za nimiž následují <figcaption>: */
img:has(+ figcaption)

Všimněte si posledního případu. Vybírá prvního z bezprostředně navazujících sourozenců v DOMu. Tady o selektoru rodiče nemůže být řeč. Navíc je to užitečné a skoro stejně nedostatkové jako ty banány za komunistů. Nebo jako selektor rodiče v CSS.

Ukázka se selektorem rodiče

Podívejme se na následující CodePen. Jsou v něm dva prvky .box. Jeden obsahuje obrázek a jeden pouze text:

<p class="box">
  Lorem ipsum…
</p>  

<p class="box">
  <img />
  <br>
  Quam doloremque…
</p>

Relační pseudotřídou :has se pak snažím zacílit boxík s obrázkem:

.box:has(img) {
  border: 5px #30680d dotted;
}

Výsledek uvidíte níže. Jen pozor, v dubnu 2022 to bude fungovat jen v Safari 15.4:

Ukázka se selektorem předchozího sourozence

V tomto demíčku se zaměříme na stylování prvků v textu, za nimiž následují jiné specifické prvky. Máme dva nadpisy, za jedním následuje odstavec, za druhým seznam položek:

<h2>Lorem ipsum, dolor sit amet</h2>
<p>
  Lorem…
</p>  
<h2>Quam doloremque…</h2>
<ul>
  <li>
    Lorem…
  </li>
</ul>

Pokud bychom ten druhý chtěli stylovat jinak, opět nemusíme složitě přidávat třídu, ale použít relační pseudotřídu :has:

h2:has(+ul) {
  border-bottom: 5px #30680d dotted;
  margin-bottom: 2rem;
}

Ani tuto ukázku neuvidíte plně funkční jinde než v Safari 15.4:

Další možnosti, občas dechberoucí

Když jsem procházel, co se selektorem :has vykouzlili jiní autoři, občas mě srdíčko poskočilo radostí. O jejich nápady se s vámi musím podělit, v tomto případě hlavně o nápady Matthiase Otta.

/* Vybere formulář, ve kterém je zatržené zatržítko: */
form:has(input[type="checkbox"]:checked) { }

/* Vybere formulář, kde jsou dvě zatržená zatržítka: */
form:has(input[type="checkbox"]:checked ~ input[type="checkbox"]:checked) { }

/* Vybere <img> ve <figure>, za nímž následuje <figcaption>: */
figure img:has(+ figcaption) { }

/* Vybere kontejner layoutu, v němž jsou dvě položky: */
.grid:has(:nth-child(2):last-child) { }

Všimněte si hlavně té poslední možnosti. Rozložení v CSS layoutu upravujeme počítáním prvků uvnitř. Jde o aplikaci takzvaných quantity queries, které už před lety popsal Heydon Pickering.

Podpora v prohlížečích

Stav podpory :has k dubnu 2022 je tento:

  • Safari nový selektor plně podporuje od poslední verze, tzn. 15.4.
  • Chrome si s :has pohrává a od verze 101 bude možné zkoušet za vlaječkou.
  • Firefox zatím nevysílá signály, že by měl podporu v nejbližší době v plánu. To nás mrzí, že… ?

V tuto chvíli by, kvůli zdaleka ne plné podpoře, asi nebylo vhodné selektor :has začít používat na veřejných webech.

Pokud byste to přes to chtěli zkusit, zmiňuji zde nápad testování podpory selektoru s možností vytvoření alternativního řešení pro přohlížeče, které :has neumí. Prostě využijeme dotaz na podporu @supports:

@supports selector(:has(*)) {
  /* Kód pro prohlížeče, které podporují :has */
}

Existují samozřejmě také javascriptové polyfilly, které funkci :has nahrazují, ale neodkážu na ně, protože z pohledu výkonu považuji nahrazování takto nízkoúrovňové funkce prohlížeče za nepěknou prasárnu.

Nevím jak vy, ale já se na podporu :has v prohlížečích docela těším.

ebook-vdcss3-prebal-final

Kniha „Vzhůru do (responzivního) designu“

Kompletní průvodce návrhem a implementací responzivních uživatelských rozhraní v e-booku a knize. Více informací.

Komentáře

Subscribe
Upozornit na
guest
4 Komentářů
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
View all comments
Jiří

Podle Can I Use je podpora :has() pouze v Safari… Takže je to vlastně absolutně k ničemu. Podle mě jsou podobné věci možná super, ale pokud nebude majoritní podpora tak je zbytečné je fakt řešit, protože stejně musím udělat CSS tak aby to fungovalo správně

Martin Hassman

To je pěkné shrnutí hlavních informací již řečených v článku:

  • Podpora je jen v Safari
  • Podobné věci jsou super
  • Dokud nebude majoritní podpora, je zbytečné to řešit

V tom shrnutí chybí už jen:

  • v Chromu 101 se brzy objeví experimentální podpora

Děkujeme za shrnutí a posíláme virtuální klíčenku. 👍

Martin Hassman

Hezky si to napsal, Martine. ❤✌

Enum a statická analýza kódu

Mám jednu univerzální radu pro začínající programátorty. V učení sice neexistují rychlé zkratky, ovšem tuhle radu můžete snadno začít používat a zrychlit tak tempo učení. Tou tajemnou ingrediencí je statická analýza kódu. Ukážeme si to na příkladu enum.