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) { }Code language: CSS (css)

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)Code language: CSS (css)

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>Code language: HTML, XML (xml)

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

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

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>Code language: HTML, XML (xml)

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;
}Code language: CSS (css)

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) { }Code language: CSS (css)

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 */
}Code language: CSS (css)

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

Odebírat
Upozornit na
guest
4 Komentářů
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
Zobrazit všechny komentáře
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. ❤✌

Cesta URL: co se děje, než se načte webová stránka

Když do adresního řádku prohlížeče napíšete webovou adresu a stisknete Enter, spustí se fascinující řetězec procesů, které propojují váš počítač s celým světem. Od překladu doménového jména na IP adresu, přes navázání šifrovaného spojení, až po vykreslení každého pixelu na obrazovce - to všechno se odehraje během zlomků sekundy. Pojďme se podívat, co se mezitím děje pod kapotou webu.

Stav SIMD v Rustu v roce 2025

Různé
Komentáře: 1
SIMD - neboli Single Instruction, Multiple Data - znamená, že procesor může jednou instrukcí zpracovat více datových prvků najednou. Typicky to znamená, že místo sčítání dvou čísel přičtete dvě sady čísel paralelně. To může přinést výrazné zrychlení například při zpracování obrazu, audia nebo numerických výpočtů. Pokud již SIMD znáte, tato tabulka je vše, co budete potřebovat. A pokud s SIMD teprve začínáte, tabulku pochopíte do konce tohoto článku