Minule sme si prešli vyčerpávajúce základy CSSka, v dnešnej časti sa poďme pozrieť na základný kameň, ktorým sú selectory.
Čo to je selector?
Ako sme si už povedali, CSS je vlastne súbor pravidiel, ktorý sa týka jednotlivých HTML elementov. Dôležitá časť, ktorá sa nachádza pred kučeravými zátvorkami a určuje, ktorého (resp. ktorých ) HTML elementov sa nasledujúce CSS pravidlá budú týkať.
selector {
color: #000;
}
selector je vo vyššie uvedenom príklade fialové slovo.
Ako to funguje?
Existuje množstvo rozličných selectorov a ich zápisov. Môžeme ich na seba naväzovať, uvádzať viac CSS selectorov naraz, ktoré budú mať rovnaké pravidlá a pod. To sú tie kaskády, ktoré pochádzajú z názvu CSS 🙂
Typy selectorov
Hviezdička *
Hviezdička označí úplne všetky HTML elementy. Všetky elementy budú bez okraja (neuvádzam dĺžkovú jednotku, keďže ide o nulu).
* {
border: 0;
}
Názov HTML elementu
Ďalší typ selectora je vlastne názov HTML elementu. Názvy sa píšu vždy bez značiek tagov (bez špicatých zátvoriek) a bez atribútov. Proste len názov html elementu. Uvádzam príklad pre HTML elementy <p>, <span>, <a> a <table> (paragraf, formatovaný text, link a tabuľku). Na tomto príklade aj vidíme, ako od seba oddeľujeme viacero selectorov. Prostredníctvom klasickej čiarky.
p, span, a, table {
border: 0;
}
Trieda (class)
Najčastejšie sa budeme stretávať s classovými selectormi. Tie sa označujú bodkou, za ktorými pokračuje názov samotnej triedy. Trieda sa už buď nachádza v HTML kóde, alebo si ju tam pridáme (pozrite zdroj napr. aj tejto stránky). Vyzerá to napr. takto:
Class je vlastne HTML atribút, ktorý môžeme pridať akémukoľvek HTML elementu. Fakt každému. <html>, <body>, dokonca aj <b>, či <i> môže mať triedu. S classou pri <i> sa stretávame najmä pri použití Fontu awesome. No a na základe zadanej triedy, si vieme pomocou selectoru odchytiť práve ten element, ktorý chceme. Viacero elementov pritom môže mať rovnakú classu. Čiže ak máme na stránke viacero elementov, pri ktorých chceme, aby mali červený text, jednoducho tým všetkým elementom popridávame rovnakú classu a pre tú jednu classu potom definujeme červenú farbu písma.
.add-to-cart {
font-size: 15px;
}
ID
IDčko je obdoba classy, líši sa v tom, že sa môže na stránke nachádzať len jeden krát! Teda IDčko je unikátny identifikátor pre každý HTML element na stránke. Aby som to upresnil, teoreticky môžeš dať rovnaké IDčko aj viacerým elementom, CSS na to reagovať bude, avšak javascript bude hádzať chybu pri zameraní elementu s daným IDčkom. HTML Validátor ti to tiež hneď vyhodí na oči.
ID rovnako môžeme pridať ľubovoľnému elementu ako HTML atribút. V CSSku selector s IDčkom potom označujeme znakom mriežky #. Význam IDčka fakt využijeme skôr v javascripte ako v CSS, každopádne, je dobré vedieť, že niečo také existuje. V praxi sa to používa síce menej ako classy, ale aj tak dosť často.
#lava-container {
font-size: 15px;
}
Potomci
Potomci, často sa označujú aj ako parent-child, už sú to trošku zložitejšie selectory, ale dajú sa veľmi rýchlo pochopiť. Použijeme buď classu, ktorá je vnorená v nadradenej classe, alebo elementy, či ich kombináciu.
Takže máme takúto html štruktúru. Najvyššie je div s triedou wrapper. V ňom je vnorený element <a> a v ňom je vnorený obrázok. Túto reťaz vieme zapísať za sebou, s medzerami. Čiže ľudskými slovami – zameriavame element img, ktorý sa nachádza v elemente a, ktorý sa nachádza v elemente s classou wrapper. Verím, že je to zrozumiteľné. Pozor, medzery musia byť.
.wrapper a img {
margin-bottom: 10px;
}
Jednotlivé vnorené elementy môžeme ľubovoľne preskakovať, nemusíme uvádzať nutne celú štruktúru. Ak vynecháme z príkladu element <a>, jednoducho sa pravidlá budú týkať tiež toho obrázka, ale selector bude menej špecifický.
.wrapper img {
margin-bottom: 10px;
}
Upresnenie elementu pomocou classy/ID
Vieme selector upresniť aj pomocou classy, alebo IDčka, ak je to potrebné. V takom prípade na názov elementu nalepíme s bodkou/mriežkou názov classy/id, čiže bez medzery
Obrázok vieme v tomto prípade zamerať aj nasledovne. Border-radius mu nastaví oblé rohy.
img.moj-image {
border-radius: 10px;
}
Priamy potomok
Prostredníctvom pravej špicatej zátvorky > označujeme priamych potomkov. Čiže selectory nasledujú bezprostredne za sebou. Ak je vnorený selector vnorený ešte v niečom inom, pravidlo sa neaplikuje – selector nezameria.
.wrapper > .moj-image {
/*Tento selector nefunguje, .moj-image nie je priamym potomkom .wrapper-a ale ešte je zanorený v elemente */
}
.wrapper > a > .moj-image {
border-radius: 10px; /*Tento selector funguje*/
}
.wrapper a > .moj-image {
/*Môžeme aj ľubovoľne kombinovať...*/
}
~ selector
Tento sexy znak napíšeš tak, že držíš alt a na číselnej klávesnici stlačíš číslo 126. Potom pustíš. Tento selector zameria element, ktorému predchádza prvý uvedený element.
- 1
- 2
- 3
- 1
- 2
- 3
p ~ ul {
list-style-type: none;
}
Selector označí len zoznam, ktorý začína na riadku 2, lebo hľadá zoznam, ktorému bezprostredne predchádza element p. Je to trošku také kostrbaté, reálne sa s ním stretávam veľmi málo.
Pomocou atribútu
Selector vieme zamerať aj pomocou presne určeného HTML atribútu. Tu je trošku taký vražedný syntax.
img[alt="My Little Pony"] {
width: 100%;
}
Po zadaní HTML elementu nasledujú hranaté zátvorky, v ktorých je atribút aj s jeho hodnotou vypísaný tak isto, ako v HTML.
Iné atribútové selectory
~= zameria element aj vtedy, ak atribút obsahuje len zadanú časť hodnoty.
img[alt~="Little"] {
}
^= zameria element vtedy, ak atribút začína na zadanú časť
img[alt^="My"] {
}
$= zameria element vtedy, ak hodnota atribútu končí zadanými znakmi.
img[alt$="Pony"] {
}
Len atribút zameria element vtedy, ak má daný atribút, bez ohľadu na jeho hodnotu.
img[alt] {
/*Zameria všetky img, ktoré majú zadaný alt*/
}
Pseudoselectory
Aby toho náhodou nebolo málo, existujú ešte aj pseudoselectory. Nie sú to pravé selectory, ale používajú sa na odchytávanie rozličných harakiri vecí, ktoré potrebujeme naštýlovať inak, ako štandardný selector. Je ich do bludu, čiže najznámejšie a najpoužívanejšie si ukážeme.
Všetky pseudoselectory sa začínajú dvojbodkou, po ktorej bez medzery nasleduje kľúčové slovo. Presudoselectory sú väčšinou nalepené na ozajstný selector, ale nie je to pravidlo.
:hover
Stav elementu pri prechode myšou. Časté pri tlačidlách, linkoch a pod.
button:hover {
background-color: yellow
}
Pri prechode myši zmení pozadie tlačidla na žlté. Dá sa použiť na všetky elementy (a, li, span, div,…). Niekedy som si myslel, že napr. v prípade hlavných menu musí byť :hover na konci selectorového reťazca, ale nie je to tak, môže sa použiť hocikde
nav.main-menu ul li:hover a {
color: #000;
}
nav.main-menu ul li a:hover {
color: #000
}
Rozdiel je ten, že podľa riadku 1 sa mi zmení farba linku už keď prídem myšou na element li. Na riadku 5 až keď prídem myšou na samotný link. Keďže tam môžu byť nejaké odsadenia a pod, lepšie bude vyzerať príklad na riadku č.1. Takže po hoveri môžu smelo nasledovať ešte ďalšie selectory.
:focus
Stav elementu, kedy je na ňom kliknuté – to sa týka väčšinou inputov vo formulároch, keď do nich píšeme.
input:focus {
border: 1px solid #000
}
Čiže keď teraz klikneš do inputu a ideš písať, okraj inputu zmení farbu na čiernu.
:active
Aktívny stav elementu. Pri tlačidle, keď na neho klikneš, tak počas doby kliku. Takmer nepoužívané, lebo nikto neklikne a nedrží sekundu tlačidlo myši, aby videl zmenu.
button:active {
background-color: #333;
}
Pri kliknutí a držaní tlačidla sa zmení jeho pozadie na tmavošedú, skoro až čiernu.
:visited
Označí už navštívený link. Ešte pred 10 rokmi to bolo moderné, dnes už nie. Z IEčka z roku 2005 si určite pamätáš nechutné modré a podčiarknuté odkazy. Tie, ktoré si už navštívil, boli ešte horšie. Fialové a podčiarknuté.
a:visited {
color: #123456;
}
:before a :after
Konečne sa dostávame k niečomu rozumnému. Pseudoselectory before a after označujú priestor pred, alebo za vybraným elementom. Väčšinou sa používajú z grafických pohnútok, napr. ak chceme pridávať vlastnú ikonu do zoznamu a pod.
ul li:before {
content: "";
width: 20px;
height: 20px;
background: green;
}
Vytvorí pred každou položkou zoznamu zelený štvorček o rozmeroch 20x20px.
:nth-child
:nth-child pseudoselector je relatívne často používaný. Pomocou neho vieme zameriavať ľubovoľný počet potomkov.
.content p:nth-child(2) {
font-size: 48px;
}
Druhému <p> elementu zo všetkých <p> elementov, ktoré sa nachádzajú v classe content vyberieme druhý a nastavíme mu veľkosť písma 48px.
Ostatné nth-child
Nth-child toho vie podstatne viac. Táto problematika je celkom zložitá a priznám sa, že ani ja ju neovládam z hlavy. Ale stačí si vygoogliť, čo človek potrebuje.
even/odd nth-child môže nadobúdať namiesto čísla aj hodnoty even/odd, čiže párny / nepárny.
table tr:nth-child(odd) {
background: #f0f0f0;
}
Každý nepárny riadok tabuľky bude mať pozadie #f0f0f0 (slabo šedá)
n označuje množinu. A tak vieme napríklad použiť n v spojení s číslom.
table tr:nth-child(3n) {
background: #f0f0f0;
}
Každý tretí riadok tabuľky bude slabošedý.
n+x označuje množinu s odskokom. A tak vieme napríklad použiť n v spojení s číslom, o koľko má naše pravidlo „odskočiť“.
table tr:nth-child(3n+2) {
background: #f0f0f0;
}
Každý tretí riadok tabuľky bude slabošedý, ale začne sa druhým riadkom. Čiže slabošedé budú riadky 2, 5, 8, 11, …
first-child označuje prvého potomka. Je to vlastne to isté, čo by bolo :nth-child(1).
table tr:first-child {
background: #f0f0f0;
}
Prvý riadok tabuľky bude slabošedý (napr. hlavička tabuľky).
last-child to isté, len sa týka poslednej položky
:not()
Tento selector sa používa vtedy, ak chceme zamerať všetky selectory, okrem uvedeného. Typické použitie pre prihlásených / neprihlásených užívateľov vo WP. Ak sa užívateľ prihlási, do <body> jeho stránky sa pridá classa is-logged. Ak teda chceme zamerať selector len na neprihlásených užívateľov, použijeme :not() a v ňom selector, ktorý chceme vylúčiť.
body:not(.is-logged) {
font-size: 19px;
}
Neprihlásení užívatelia budú mať veľkosť písma 19px. Niečo podobné v Elementore som robil tu.
Ďalšie pseudoselectory
Ďalšie pseudoselectory sa používajú navlas rovnako. Len vždy označujú niečo iné.
:checked /*Označí všetky zaškrtnuté checkboxy*/
:disabled /*Všetky zakázané inputy*/
:optional /*Všetky nepovinné inputy*/
:required /*Všetky povinné inputy*/
:invalid /*Všetky inputy, ktoré majú nesprávnu hodnotu - napr. keď do input email vložíš číslo a pod.*/
:root /*Označuje root element, väčšinou sa používa v preprocesoroch na nastavenie premenných a pod.*/
Je ich ešte veľa, ale máloktoré z tých, čo som neuviedol, sa aj používajú v praxi. Celý zoznam tu.
Sila kaskád
Musím tu ešte spomenúť, že ako to celé teda funguje. Jednotlivé pravidlá sa aplikujú
- Podľa svojej sily
- Podľa poradia
Podľa svojej sily
Každý typ selectora má svoju silu.
!important: Najsilnejší a neprekonateľný je zápis hodnoty s !important. Ten neprekoná nikdy nič. Preto sa mu treba vyhýbať najviac ako sa dá, lebo prepísať sa dá potom len iným, lepšie cieleným !important-om.
selector {
color: #000!important;
}
Inline CSS zápis je druhý najsilnejší, lebo sa týka len konkrétneho HTML elementu.
Nadpis č.1<
ID je tretí v poradí. Za ním class. Potom element. Na záver selector hviezdička *.
Ak ide o rovnaký typ selectoru, potom vyhráva ten, ktorý je viac špecifický.
.myclass {
color: black;
}
.header .myclass {
color: white;
}
Víťazná farba bude biela, lebo .header .myclass je špecifickejšia ako len .myclass.
Podľa poradia
Ak sú dva selectory navlas rovnaké, aplikuje sa pravidlo, ktoré je uvedené neskôr. Prehliadač totiž CSS spracováva v poradí, v akom je napísané, takže on síce na milisekundu nastaví prvé pravidlo, v zapätí ho však hneď prepíše na druhé – neskoršie pravidlo.
.mojatrieda {
color: black;
}
.mojatrieda {
color: white;
}
Víťazná farba bude biela, lebo nasleduje neskôr. Pravidlo o poradí je však podriadené pravidlu o sile, ak by som to dal takto:
div .mojatrieda {
color: black;
}
.mojatrieda {
color: white;
}
Víťazná farba by bola čierna, lebo špecifickejší selector je nadradený poradiu. Takže čierna farba vyhraje boj aj vtedy, ak sa spracuje skôr. Inými slovami – selector s bielou neprepíše selector s čiernou, aj napriek tomu, že by podľa poradia mal. Podľa sily selectoru však nemá.
Pravidlo o poradí neplatí len v rámci jedného súboru, ale platí v rámci celej webovej stránky. Čiže keď sa ti v headeri loadujú externé CSSka takto:
Tak všetky pravidlá pochádzajúce z responsive.css budú podľa pravidla o poradí uprednostnené pred pravidlami zo style.css, lebo nasledujú v kóde neskôr.
Ešte toto musíš vedieť!
Do jedného HTML elementu vieme zadať viacero class. Jednotlivé classy od seba v HTML oddeľuješ medzerou. Názvy môžu obsahovať len alfanumerické znaky, žiadne dĺžne ani mäkkčene. To isté platí pre ID.
Ak by som teraz cez CSS chcel zamerať viac class naraz, jednoducho budem reťaziť pomocou bodky. Môžem pri tom reťaziť všetky dostupné classy, alebo len niektoré. Ak by sme dali medzeru, selector bude automaticky hľadať vnorenú classu (po medzere), ktorú nenájde.
div.prva-classa.druha-classa.stoprva-classa {
/*Bude fungovať*/
}
IDčko musí byť jednoslovné pomenovanie. Ak potrebuješ viacslovné, musíš nahradiť medzery pomlčkami, alebo podčiarkovníkmi.
Ak tomu stále jaksi nevieš prísť na chuť, odporúčam túto hru. Je to zábava a pochopíš silu selectorov a ich význam.