Osobní blog
Soukromý, neprofesní mikroblog.
Článek č. 144
Naposledy upraveno 02. 06. 2024 11:53
Tvorba webu – CSS: Pseudotřída :has() pro nastylování elementu podle jeho obsahu. Převratná (převrácená) definice zdola nahoru, zevnitř ven!
Kaskádové styly CSS pro definici vzhledu webu dostaly novou pseudotřídu (pseudo-class) ':has()'.
Ta umožňuje definovat styl pro prvek, který má něco námi sledovaného v sobě, uvnitř, jako svého potomka.
To je velmi zajímavá novinka. Dá se říci, že převratná.
Převratná doslova, protože je to opačná možnost proti tomu, co bylo v CSS snad odjakživa z jeho kaskádové podstaty.
Snad vždycky jsme mohli v CSS určit vzhled prvku, který je zanořen v něčem.
A až novou CSS pseudotřídu ':has' budou významně podporovat prohlížeče, tak budeme moci v CSS určit vzhled prvku, v němž je zanořeno něco!
A to včetně reakce na stav toho něčeho uvnitř (např. pseudotřída :checked toho něčeho uvnitř) nebo na další kontext (počet toho uvnitř, např. pomocí nth-child apod.).
Nechci to tu ale popisovat od prostředka,
chci to vzít systematicky srozumitelně od lesa,
takže začnu tím, co v CSS bylo snad vždy, a půjdu postupně vpřed.
Pokud jste v CSS začátečníci, falešní začátečníci nebo jste s CSS dlouho nepracovali,
tak čtěte vše od bodu 1 včetně.
Pokud si dobře pamatujete, co jste se kdysi z CSS naučili, občas to používáte, orientujete se v tom, pracujete v CSS,
ale nevíte, k čemu je dobrá pseudotřída :focus-within,
tak můžete přeskočit body 1 a 2 a můžete číst od bodu 3.
Pokud běžně pracujete v CSS
a běžně používáte pseudotřídu :focus
a už jste aspoň někdy použili pseudotřídu :focus-within,
tak můžete přeskočit body 1 až 3 a můžete číst od bodu 4.
Úvod je dlouhý, ale věřím, že pro ty, kdo něco dle právě uvedeného rozcestníku neznají, má smysl. Pro ně tu je.
Samotná novinka úplně dole, společná pro všechny, už je docela stručná.
Jdeme na to:
--------------------------------------
1) Definice shora dolů (zvenku dovnitř)
Kaskádové styly CSS pro definici visuálního stylu webu odjakživa umožňují definovat, jak má vypadat něco, co je v něčem.
a)
CSS kód 'p a { font-size: 1.1em; }' zvětší písmo takového odkazu (a), který je v odstavci (p).
V HTML kódu to bude vypadat např.:
'<p> <a href="">Kontakt</a> </p>'
nebo
'<p>
<img src="" alt="" />
<span> <a href="">Kontakt</a> </span>
</p>'
Oba takové HTML zápisy budou znamenat,
že odkaz (a) bude CSS zápisem 'p a {}' ovlivněn.
Výše uvedený CSS kód nemá žádný vliv na odkaz, který v hierarchii nad sebou žádný odstavec jako předka nemá (není v odstavci).
b)
Totéž lze definovat i pouze pro přímé vnoření, čili můžeme definovat, jak má vypadat něco, co je přímo v něčem. Přímo, nikoliv přes koleno.
Zápis 'p>a { font-size: 1.1em; }', kde je mezi odstavcem (p) a odkazem (a) místo mezery většítko '>', zvětší písmo takového odkazu, který je přímo v odstavci.
Takový zápis má vliv jen na takový odkaz, který má nad sebou odstavec jako přímého předka, jako přímého rodiče.
Takový CSS zápis s většítkem místo mezery 'p>a {}' bude mít vliv např. na odkaz (a) z tohoto HTML kódu:
'<p> <a href="">Kontakt</a> </p>'
A bude mít vliv i na odkaz (a) z tohoto HTML kódu:
'<p>
<img src="" alt="" />
<a href="">Kontakt</a>
</p>'
Protože odkaz (a) je umístěn přímo v odstavci (p), jako jeho přímý potomek;
ten obrázek (img) na to nemá vliv, ten je na stejné úrovni jako odkaz (a).
Bavíme se o úrovni zanoření, o hierarchii; nikoliv o pořadí.
Takovým CSS zápisem s většítkem místo mezery 'p>a {}' ale nebude ovlivněn odkaz (a) z tohoto HTML kódu:
'<p>
<span> <a href="">Kontakt</a> </span>
</p>'
Protože tento odkaz (a) není přímý potomek odstavce (p).
Je to potomek přes koleno, je mezi nimi ještě span.
Proto takový odkaz obalený spanem reaguje jen na CSS zápis s mezerou 'p a'.
Příp. reaguje i na 'p>span>a' nebo na jiné relevantní zápisy.
--------------------------------------
2) Pseudotřída :hover
Pokud uživatel na něco najede kurzorem myši, má dotyčný element po dobu přítomnosti kurzoru myši aktivní pseudotřídu ':hover'.
V praxi tu pseudotřídu obvykle dostane více elementů současně,
protože ten jeden kurzor myši je současně na více elementech.
Budu se držet výše použitého příkladu s tímto HTML kódem:
'<p>
<img src="" alt="" />
<span> <a href="">Kontakt</a> </span>
</p>'
Pokud do toho nevstoupí pokročilejší práce s CSS, především tedy pozicování, nevhodně použitý float, apod.,
tak lze předpokládat, že když uživatel najede kurzorem myši na odkaz (a), tak současně najel i na span a na odstavec (p).
Protože ve výchozím stavu, pokud to nerozhasíme pozicováním, floatem, apod., bude platit,
že všude tam, kde je tento odkaz (a), je současně tento span,
a všude tam, kde je tento span, je současně tento odstavec (p).
Takže po dobu, kdy bude kurzor myši na odkazu (a), bude platit, že:
- tento konkrétní element a bude v tu chvíli a:hover
- tento konkrétní element span bude v tu chvíli span:hover
- tento konkrétní element p bude v tu chvíli p:hover
Protože ta myš je i na spanu a na odstavci, ne jen na odkazu.
Z vnitřního technického hlediska tedy jde o to, že se pseudotřída :hover objeví na různých elementech současně (proto můžeme v CSS napsat třeba 'p:hover {}' a daný CSS zápis se pro tento odstavec použije).
Z praktického hlediska to pro kodéra ve většině situací je první vlaštovka, kdy může alespoň v případě :hover nějak reagovat na něco, co se děje uvnitř (i když se to vlastně děje na více úrovních hierarchie současně).
--------------------------------------
3) Pseudotřídy :focus, :focus-within
a) Pseudotřída :focus a k čemu je dobrá (ovládání webu klávesnicí)
Nejdříve udělám krok zpět, a vysvětlím, co je pseudotřida ':focus'.
Protože podle mnoha dnešních profesionálně vyrobených moderních webů mám pocit, že většina dnešních kodérů neví, že počítač má jít ovládat klávesnicí, sami ho tak neumějí ovládat, a tudíž ani neumějí web nakódovat správně tak, aby šel klávesnicí ovládat. Soudě dle tristního stavu dnešních moderních webů, kterým definice ':focus' obvykle chybí, jakkoliv je to neodpustitelné. (I když se to posledních hodně týdnů nebo málo měsíců snaží prohlížeč Firefox dohánět za chodu a tu práci dělat za kodéra.)
Pseudotřída ':focus' je klávesnicová analogie pseudotřídy ':hover'.
(To platí v případě odkazů.
Kromě toho se ':focus' aktivuje u prvků formuláře – a to i myší nebo dotykovým displejem.
A trochu pokročileji se dá používat pro zobrazování nástrojů pro obsluhu klávesnicí, např. pro zobrazování odkazů pro skok do jiné části stránky. Zkuste hned po načtení stránky, ještě před akcemi myší, párkrát stisknout klávesu 'Tab' u mě na webu adamek.cz nebo ve výsledcích hledání na Googlu, a uvidíte, že se objeví něco skrytého, užitečného pro uživatele klávesnice.
)
Pokud na nějaký element jako uživatel najedete kurzorem myši
nebo na něho tapnete (čili jakoby kliknete, ale na dotykové obrazovce),
tak ten element dostane pseudotřídu ':hover'.
To všichni vědí a běžně používají.
Pokud na nějaký element jako uživatel skočíte klávesou 'Tab'
nebo na něho skočíte klávesovou zkratkou, kterou kodér definoval parametrem acceskey (např. 'accesskey="4"' pro hledání, dle české normy) daného elementu
(ve windows se použije kombinací Alt+Shift+horní_číslice)
nebo na ten element kliknete nebo tapnete,
tak ten element dostane pseudotřídu ':focus'.
Což dnes asi skoro nikdo neví, protože to skoro žádný profesionálně vyrobený web nepoužívá, asi proto, že skoro všichni klikají nebo tapají a málokdo používá klávesnici.
Což je tragédie. Hlavně pro přístupnost, použitelnost, efektivitu, ergonomii, čas a nervy uživatele.
Např. jednoduchý CSS zápis ' *:focus { background: yellow; } ' při jinak bílém pozadí a černém textu odvede velmi mnoho práce.
Uživatel jednak vidí, kde se právě s klávesnicovým kurzorem nachází (kde se bude něco dít, když např. začne psát nebo stiskne kurzorovou šipku na klávesnici)
a jednak má zajištěn lepší kontrast (při správné volbě barev), aby snadněji a spolehlivěji viděl, co zadává.
(Dříve, asi tak do r. 2010 (velmi zhruba), bylo vhodné úplně stejně definovat i pseudotřídu ':active', která se v některých praktických příkladech chovala podobně jako ':focus' a některé prohlížeče ji tehdy vyžadovaly, protože na :focus nereagovaly. Ale to je jen zajímavost z historie. Dnes stačí ':focus'.)
Prosím, definujte vzhled pro ':focus'.
Když už nic jiného, tak stejně jako pro ':hover'.
Takže tam, kde jste doposud psali 'váš_element:hover { váš_vzhled }'
prostě budete nově psát 'váš_element:hover, váš_element:focus { váš_vzhled }'.
Už jen tím odvedete spoustu práce a uživatelům tím dost pomůžete.
---
Vždyť na spoustě dnešních webů ani není poznat, na kterém odkazu člověk právě klávesnicovým kurzorem je.
Zkuste si to:
Navštivte nějaký web, a pak pracujte s klávesami/kombinacemi:
- Tab
- Shift+Tab
- Enter
- Ctrl+Enter
(nový panel, podobně jako Ctrl+klik nebo klik_scrollítkem; pokud do toho nehodí vidle autor JS kódu, což se bohužel masivně děje např. na zpravodajských i jiných webech nejmenovaného českého internetového giganta)
Do adresního řádku se dostanete Ctrl+L.
Nebo kdysi F6 (funguje i dnes).
Potvrdíte enterem.
Rychlý skok do políčka hledání na daném webu:
- Manuál PHP (php.net):
Alt+Shift+S, asi jako 'search', ale vy to tak nekódujte, může se to poprat se "&Soubor"
- Celý ekosystém Wikipedie:
Alt+Shift+F, asi jako 'find', ale vy to tak nekódujte, může se to poprat s "&File"
- Česká norma, kterou málokdo zná a respektuje, ale lepší/jiná asi neexistuje:
Alt+Shift+4 (Alt+Shift+č),
můžete si vyzkoušet na mém webu.
Číslice 1 – 9, 0 jsou nekolizní s položkami menu běžných prohlížečů;
i když je pravda, že v doporučeních pro přístupnost webu už se od klávesových zkratek zase ustupuje kvůli možným kolizím s uživatelskými zkratkami.
Jablíčkáři si místo 'Alt+Shift' doplní klávesovou kombinaci svého webového prohlížeče, to je věc základní obecné obsluhy svého počítače, nikoliv daného webu.
Ve Windows to 'Alt+Shift' funguje snad napříč všemi běžnými prohlížeči.
---
Když budete chtít pro uživatele a jeho zážitek udělat něco více,
můžete definovat vzhled pro :focus trošku jinak než pro :hover,
aby poznal, kde má na dané stránce kurzor klávesnice, a kde kurzor myši.
Např. při černém textu na popředí krásně funguje
sytě žluté pozadí pro ':focus', když tam ten uživatel už opravdu je,
a světle žluté pozadí (čili něco mezi sytě žlutým a bílým) pro ':hover', když tam ten uživatel jen projíždí myší a ještě tam neklikl.
Ono to nakonec pomůže i myšařům.
Ale pokud se vám nechce definovat dva různé vzhledy, tak už jen to připsání ':focus' k ':hover' je záslužný a efektivní počin.
Focus je strašně důležitý pro odkazy, aby uživatel vůbec měl možnost vytušit, kde vlastně je (zkuste si to s klávesnicí na dnešních webech bez stylů pro focus a zapláčete),
a velmi užitečný i pro inputy ve formulářích, aby uživatel nemusel hledat, kde je.
--------------------------------------
b) Pseudotřída :focus-within
Před pár lety přišla skvělá novinka. Pseudotřída ':focus-within'.
Pseudotřída, která umožňuje reagovat na to, co se děje uvnitř.
Vrátím se zase k tomu HTML kódu, který jsem použil už výše:
'<p>
<img src="" alt="" />
<span> <a href="">Kontakt</a> </span>
</p>'
Když uživatel naskáče tabulátorem (klávesa 'Tab') na tento odkaz,
tak ten odkaz bude v tu chvíli a:focus.
To už víme.
A, pozor, to je ta geniální novinka nedávných let,
ten odstavec, který je okolo, bude v tu chvíli p:focus-within.
Úžasné. Když to přišlo, bylo to jako dar z nebes.
Konečně člověk může definovat kaskádově v opačném pořadí zdola nahoru (zevnitř ven) nejen :hover pro myš ad bod 2 výše, ale nově i :focus pro klávesnici.
Pokud chcete vidět praktické využití, koukněte z PC (věřím, že snad vč. Maca; čili myšleno ne z dotykového mobilu) u mě na webu adamek.cz (kde pravděpodobně teď čtete tento článek) dolů na patičku.
Standardně má pro ozdobu na pozadí kladívkovou barvu (tečkovanou), jako měly palubní desky některých starých aut.
Ale jelikož toto pozadí nemá dobrý kontrast proti popředí, tak toto pozadí ruším jednak pro najetí myší (:hover) a jednak už pár let také pro naskákání klávesnicí (:focus-within).
Obyčejný ':focus' by mi tam nebyl nic platný, protože focus má odkaz, nikoliv ten div okolo něho!
Totéž pravý sloupec téhož webu (adamek.cz).
Billboardy s novinkami, vpravo od silnice, mám standardně pomocí CSS zkosené, abych vytvořil jakýsi 3D efekt,
ale ve chvíli, kdy se jimi uživatel zabývá, je narovnávám, abych zkosením nekomplikoval čtení.
Narovnání probíhá pro ':hover' (najetí myší) nebo pro ':focus-within' (naskákání klávesnicí na odkaz uvnitř divu).
Stačí najet na jeden odkaz, a díky focus-within u obalu, např. u odstavce v HTML ukázce výše nebo u divu u mne na webu,
mohu změnit vzhled všeho relevantního, všeho v obalu.
Čili i obrázku (img) v HTML kódu výše, i všeho v patičce nebo celého pravého sloupce a všech billboardů v něm u mne na webu.
Když jsem k těmto zde popsaným účelům v patičce a v pravém sloupci pseudotřídu ':focus-within' na svém webu před pár lety zavedl,
byl s jejím použitím nespokojen CSS validátor od W3C.
Ale dnes už je s ní v pohodě, už ji zná, už s ní nemá problém.
--------------------------------------
4) Nová pseudotřída :has
a) S čím přišel Martin Michálek pod značkou Vzhůru dolů:
Před pár dny, čili v srpnu 2022, jsem se na FB a následně webu "Vzhůru dolů", kde Martin Michálek publikuje zajímavosti ze světa CSS, dočetl, že máme novou pseudotřídu ':has'.
Resp. budeme mít, až ji budou významně podporovat prohlížeče.
FB post Vzhůru dolů:
25. 8. 2022
https://www.facebook.com/VzhuruDolu/
(Odkaz na post najdete dole.)
Článek na webu Vzhůru dolů:
12. 4. 2022
Relační selektor :has – zdaleka ne jen selektor rodiče
https://www.vzhurudolu.cz/prirucka/css-selektor-has
V článku na webu Vzhůru dolů jeho autor Martin Michálek popisuje a ukazuje, jak lze novou pseudotřídu ':has' využít.
Jak už jste asi vytušili z tohoto mého článku, základním cílem je možnost určit vzhled něčeho, co má v sobě něco.
Martin Michálek za citování zahraničních autorů, hlavně Matthiase Otta, ve svém článku ukazuje zajímavé možnosti, jako např.:
Formulář se zaškrtnutým checkboxem
form:has(input[type="checkbox"]:checked) { }
Formulář se zaškrtnutými dvěma checkboxy
form:has(input[type="checkbox"]:checked ~ input[type="checkbox"]:checked) { }
Element, v němž jsou právě dvě položky
.grid:has(:nth-child(2):last-child) { }
(Je tam toho více, vybral jsem jen něco na ukázku.)
b) Co na to já:
Tuto novou možnost považuji za velmi zajímavou.
Jak tu základní možnost určit v CSS element podle jeho obsahu, která zatím nebyla (prakticky ještě tak úplně není; ale snad bude);
tak i ty rozšířené možnosti definice pro reakci na dění uvnitř nebo na počet prvků uvnitř.
A jak je asi zřejmé z celého mého úvodu k této novince výše,
z těch bodů 1 až 3, kterými jsem neváhal začít,
považuji tu novou pseudotřídu ':has()' za zajímavé obecnější rozšíření možností konceptu reakce na něco uvnitř,
který před lety přišel s pseudotřídou :focus-within (ad bod 3 tohoto článku, výše).
Můj tip (!):
Pokud byste chtěli použít CSS zápis např. 'div:has(:focus)',
tak místo toho použijte raději 'div:focus-within'.
Předpokládám, že by to mělo být totéž, že by se to mělo chovat stejně,
ale rozdíl je v tom, že pseudotřída ':focus-within' je s námi už pár let, a tudíž má oproti novince ':has()' mnohem lepší podporu v prohlížečích.
Stručný komentář:
Když už jsem zde vše sdělil snad v rozumné posloupnosti od začátku,
tak na závěr přiložím svůj komentář z 26. 8. 2022 pod FB postem z 25. 8. 2022 na FB stránce Vzhůru dolů,
kde celou věc komentuji sice stejně nadšeně a mnohem stručněji, ale nutno přiznat, že tak trochu od prostředka:
Velmi zajímavé.
Před pár lety jsem začal používat :focus-within, což je skvělá věc pro práci s backgroundem, kontrastem nebo čímkoliv v kontextu obsluhy webu klávesnicí.
Když focus-within přišel jako novinka, tak kvůli němu naříkal CSS validátor od W3C, ale už se s ním skamarádil.
A tohleto :has je zajímavé obecnější rozšíření toho konceptu reakce na něco uvnitř.
Ono by asi focus-within šlo přepsat jako :has(:focus), k čemuž ale není důvod, když focus-within coby starší novinka má lepší podporu :)
(Čili tip: Pokud někdo chcete použít :has(:focus), tak radši použijte starší (podporovanější) :focus-within.)
Snad odjakživa tuhle reakci obalu na něco uvnitř umí ve většině praktických případů :hover, pokud do toho nevstoupí nějaké pozicování apod.;
dlouho se zapomínalo na možnost např. změny pozadí při obsluze klávesnicí, což před lety vyřešil focus-within;
a je docela příjemné, že to teď pokračuje dál, pro obecnější použití, tím :has.
Jak často naříkám na dekadentní směr vývoje SW, HW, elektroniky, aut, bílé techniky, a vlastně všeho,
tak mám naopak dlouhodobě radost z vývoje PHP a CSS, protože ty jdou dlouhodobě dobrým a smysluplným směrem,
a novější verze jsou lepší než ty starší, což jinak ve společnosti dávno neplatí.
----------------------
Ilustrační obrázek:
Výřez ze snímku obrazovky z jedné mé intranetové aplikace
(interní/neveřejné databázově orientované webové aplikace)
Související odkazy
- https://www.facebook.com/VzhuruDolu/posts/pfbid087AQJhrtYxQAoi4AK4aaiV7iSxBgU5tYrkSQacLTB2ccEFaEiYXpA6v9pnVJMNSql
- https://www.vzhurudolu.cz/prirucka/css-selektor-has
- https://www.adamek.cz/clanky/popularne-odborne/validita-html-kodu/ (14. 09. 2013)
- https://www.adamek.cz/blog/?blogpost=147 (10. 09. 2022)
Líbil se Vám článek?
Zpětná vazba – hlasování
Hlasy se na serveru připočítají k počitadlům pro tento článek, např. kolikrát tento článek někoho pobavil a kolikrát tento článek někomu pomohl.
Neukládají se jednotlivá hlasování (vzájemná kombinace hlasů, datum, čas, ani jiné údaje).
Proto nemá smysl odesílat prázdný hlas, nemělo by se co k čemu přičíst.
Ve Vašem prohlížeči nebude uložena žádná informace (cookies) o tom, že už jste hlasovali.
- Ve Vašem prohlížeči tedy nebude vidět, jak jste hlasovali.
- Kdykoliv budete moci hlasovat znovu, pokud Vám článek opakovaně pomůže (pobaví Vás, potěší, …).
- Pokud Vás právě u jednoho počítače sedí více, mohou postupně hlasovat další lidé.
Počítám člověkohlasy, nikoliv lidi.
Tedy kolikrát článek někomu pomohl,
nikoliv kolika lidem pomohl.
Třikrát potěšeného jednoho čtenáře počítám stejně jako tři různé jednou potěšené čtenáře.
Každý má do budoucna neomezený počet hlasů.
Když zapomenete, že jste pro tento článek už hlasovali, nevadí – když Vám někdy v budoucnu bude např. užitečný znovu, tak mu znovu pošlete hlas, že Vám byl užitečný.
Štítky, labels, kategorie, témata, tagy, hashtagy
(ve vývoji)#historical-technology #science-technology #electro-ict