Flex
Ako sme naznačili v predošlej lekcii, ďalším spôsobom tvorby layoutu je použitie vlastnosti display: flex
. Ide o lineárny layout (t. j. v riadku alebo stĺpci), ktorý uľahčuje mnoho problémy, ktoré sa musia inak riešiť rôznymi, nie práve šikovnými okľukami. Ako ukážkovú situáciu, kde je vhodné používať flex, môžeme uviesť fotogalériu, kde každá fotografia má svoju pevnú šírku, avšak chceme aby medzi fotografiami boli rovnaké rozostupy a pokiaľ sa fotografie nezmestia do jedného riadku, automaticky sa usporiadajú do dvoch, resp. viac. Úplne najdôležitejšia je poznámka, že táto vlastnosť sa správa responzívne, čiže sa nemusíme zaoberať tým, akú šírku má materský kontajner, v ktorom sú fotky povkladané.
Pre upresnenie: Grid (minulá lekcia) slúži na dvojrozmerný layout, čiže ho používame na tvorbu celkového layoutu stránky -- ide v podstate o akúsi responzívnu tabuľku, kde jednotlivé bunky vypĺňame jednotlivými sekciami stránky. Flex je jednorozmerný layout, ktorý používame už na nejakú podčasť stránky, čiže, ako sme spomínali, rôzne fotogalérie, položky tovaru v e-shope a pod. Flex vo všeobecnosti nie je úplne vhodný na tvorbu celkového layoutu, nakoľko pri komplikovanejšom rozložení stránky sa môže správať chaoticky. Hoci je možné nájsť rôzne návody, ako sa s tým popasovať, grid je predsa len na tento účel vhodnejší, zrozumiteľnejší a názornejší.
Podobne ako grid, aj flex sa formátuje na dvoch úrovniach:
- materský kontajner (flex container) -- nastavujeme tu smer toku, zalamovanie a pozíciu položiek (dcérskych kontajnerov) v rámci materského kontajnera, všeobecne slúži na globálne nastavenie flexu,
- položky (flex items) -- tu nastavujeme v akom poradí sa zobrazia položky materského kontajnera, prípadne vlastné zarovnanie, rozmery a rast.
Flex container
Pokiaľ chceme, aby sa položky v materskom kontajneri zobrazili ako flex, do príslušného selektora materského kontajnera musíme vložiť vlastnosť display: flex;
.
Keďže flex (materský) kontajner zvyčajne obsahuje viacero položiek, vieme nastaviť smer a poradie v akom sa budú zobrazovať pomocou vlastnosti flex-direction
. Taktiež vieme povedať, že pokiaľ sa položky nezmestia do jedného riadku (stĺpca) môžu sa zalomiť do ďalšieho riadku pomocou vlastnoti flex-wrap
. Tieto dve vlastnosti môžu nadobúdať nasledovné hodnoty:

ÚLOHA
Teraz si otvorte na novej karte nasledovnú ukážku a pomocou možnosti "Preskúmať" meňte jednotlivé hodnoty v selektore .container
vlastností flex-flow
a flex-wrap
Obzvlášť sa zamerajte na to, čo sa stane, keď zmeníte šírku okna tak, aby sa jednotlivé položky A, B, C, D, E nezmestili do jedného riadku pri hodnotách wrap
a nowrap
vlastnosti flex-wrap
.
Ďalej okrem toku flex kontajnera vieme formátovať aj vodorovné a zvislé rozmiestnenie jednotlivých položiek (budeme predpokladať flex-direction: row;
). Ako vidíme, východisková možnosť v našom prípade je, že všetky položky sú naukladané za sebou v ľavom hornom rohu.
Pokiaľ chceme meniť vodorovné rozmiestnenie jednotlivých položiek použijeme vlastnosť justify-content
, ktorá môže nadobúdať nasledovné hodnoty:

Sledujte, ako sa mení rozloženie položiek v kontajneri (biele miesto okolo farebných obdĺžnikov). Jednotlivé názvy jasne určujú, akým spôsobom sa to vykoná. Dôkladne si však všimnite, aký je rozdiel medzi hodnotami space-around
a space-evenly
.
Podobným spôsobom vieme meniť aj zvislé rozloženie pomocou vlastnosti align-items
. Prvé tri možnosti sú rovnaké ako vo vodorovnom umiestnení. Avšak, je tu aj možnosť stretch
, ktorá roztiahne jednotlivé položky na celú výšku materského kontajnera.

Ako vidíme, existuje aj vlastnosť align-content
, ktorá môže nadobúdať rovnaké hodnoty ako justify-content
. Rozdiel oproti align-items
je v tom, že tu nezarovnávame položky ako celok, ale zarovnávame jednotlivé riadky. Taktiež, táto vlastnosť v niektorých prípadoch prebije to, čo sme nastavili v align-items
. Názornejšie si vyskúšajte toto správanie na nasledovnej úlohe.
ÚLOHA
Pracujeme opäť v ukážke 1 a pomocou možnosti "Preskúmať" budeme meniť jednotlivé hodnoty v selektore .container
.
1. Nastavte si šírku okna tak, aby ste mali všetky položky v jednom riadku. Skúšajte meniť hodnoty vlastností justify-content
a align-items
a sledujte ako sa mení biele miesto okolo jednotlivých položiek.
Ako dokonale vycentrovať položky (vodorovne aj zvisle) vzhľadom na .container
využitím flexu?
Obidvom vlastnostiam nastavíme hodnoty center
.
2. Teraz si okno zúžte tak, aby ste položky mali v dvoch riadkoch. Kliknutím do okna s vlastnosťami selektora .container
pridajte vlastnosť align-content
a sledujte ako sa správajú hodnoty. Všimnite si najmä, že hodnoty space-...
sa správajú vzhľadom na riadky rovnako, ako je to v prípade justify-content
.

Poznámka: na začiatku sme si uviedli predpoklad, že uvažujeme flex-direction: row
. To má priamy vplyv na to, ako sa správajú hodnoty flex-start
a flex-end
vzhľadom na kontajner -- čiže, ide o začiatok/koniec v smere flexu -- a vlastne to aj vysvetľuje, prečo sa nepoužívajú napr. hodnoty left, top
a podobne. Totiž pokiaľ by sme použili napr. flex-direction: row-reverse
, hodnota flex-start
by reprezentovala pravý horný roh, analogicky odvodíme hodnotu pre koniec flexu. Pri používaní rôznych smerov toku preto treba na toto dávať pozor 😉.
Flex items
Druhá úroveň, na ktorej nastavujeme flex, sú samotné položky. Podrobnejšie si vysvetlíme dve dôležité vlastnosti, ktoré majú najväčšie praktické využitie. Tieto vlastnosti nastavujeme už pre jednotlivé položky, čiže v našom prípade pre selektory .A
, .B
, .C
, .D
a .E
.
Pre zobrazenie stránky na rôznych zariadeniach môžeme požadovať, aby sa jednotlivé položky zobrazovali v rôznom poradí. Poradie položiek vo flex kontajneri vieme meniť pomocou vlastnosti order
. Je dôležité, aby všetky položky mali svoj vlastný a jedinečný selektor (tak, ako to máme napr. v ukážke, každá z piatich položiek je trieda charakterizovaná iným písmenom), pokiaľ im túto vlastnosť chceme priradiť. Vlastnosti order
môžeme priradiť ľubovoľnú celočíselnú hodnotu (t. j. aj záporné čísla). Jednotlivé položky sa následne zobrazia od najmenšieho po najväčšie. Východiskovo sa položky zobrazia v takom poradí, ako sú zadané v HTML kóde, čiže pokiaľ dvom rôznym položkám priradíme rovnakú hodnotu order
, zobrazia v takom poradí, ako sú napísané v HTML.
V praxi to vyzerá nasledovne (vyskúšajte si to na ukážke 1 meniť pre rôzne situácie):

Vlastnosť display: flex
spôsobí, že položky budú zaberať len toľko miesta koľko je nutné (v našom prípade je okolo písmen nastavený len padding
). V zásade môžeme každej položke nastaviť aj pevnú šírku, resp. výšku pomocou vlastností width
a height
. Avšak flex nám umožňuje nastavovať aj relatívne šírky (pokiaľ sú položky v riadku) jednotlivých položiek vzhľadom na materský kontajner. Robí sa to pomocou vlastnosti flex-grow
, ktorej môžeme nastaviť ľubovoľnú hodnotu väčšiu, resp. rovnú 1
(táto je východisková). Pokiaľ nastavíme niektorej položke hodnotu flex-grow: 2
, znamená to, že táto položka sa pokúsi zabrať dvakrát viac miesta, ako ostatné položky v kontajneri.

Avšak je dôležité povedať, že nie za každú cenu. Takáto položka nezaberie dvojnásobok miesta, pokiaľ by to znamenalo, že by mala vytlačiť nejakú inú do nového riadku. A naopak, pokiaľ je v riadku miesta dosť, pokojne zaberie aj viac ako dvojnásobok miesta, len aby bol riadok vyplnený (pravedpodobne kvôli tomu má táto vlasnosť názov "grow"). Vyskúšajte si to na ukážke nasledovne:
ÚLOHA
Pracujeme opäť v ukážke 1 a pomocou možnosti "Preskúmať" pridajte vlastnosť flex-grow: 2
niektorej položke. Následne meňte šírku okna tak, aby sa položky zalomili do druhého riadku a tak, aby rastúca položka viditeľne zabrala viac ako dvojnásobok miesta oproti ostatným.
Ďalej vyskúšajte viacerým položkám nastaviť rôzne hodnoty flex-grow
a sledujte, ako správa ich šírka.
Priamočiarejším spôsobom, ako nastaviť šírku v prípade riadkového zobrazenia (a výšku v prípade stĺpcového zobrazenia) je pomocou vlastnosti flex-basis
, kde zadávame konkrétnu hodnotu, napr. v pixeloch. Ďalšie nastavenie, ktoré môžeme položke priradiť je align-self
, ktoré pre tú danú položku prepíše hodnotu, ktorá je zapísaná vo vlastnosti kontajnera align-items
(čiže, ostatné zostanú zachované).
Poznámka na záver: Všetky vlastnosti, ktoré sme si uviedli či už pre flex alebo grid, sa aplikujú len vtedy, keď v príslušnom materskom kontajneri zadefinujeme príslušnú vlastnosť display: flex
, resp. display: grid
. Preto, keď ich chceme využívať, netreba na to zabudnúť.