Grafický interaktívny tutoriál - ako funguje "flex"


Tento "interaktívny návod" je inšpirovaný skvelým videom od "codeSTACKr" - Learn CSS FLEXBOX in 20 Minutes kde je toho ešte o kus viac (v angličtine) a odporúčam si ten návod pozrieť. Mimochodom podobný návod má tento autor aj pre "grid". Tiež odporúčam pozrieť, ak vás grid zaujíma. Určite sa k nemu časom dostanete... Aj na grid som si spravil takúto základnú pomôcku: "grid" - zoznám sa s mriežkou pri tvorbe webu.


Nie je to úplne plnohodnotný a komplexný sprievodca ako funguje flex, ale je tu veľmi názorne ukázaný základ jeho fungovania. To hlavné na pochopenie fungovania, prípadne možností kde to využiť. A môže to byť taká rýchla interaktívna nápoveda. K daktorej kapitole je občas doplnený odkaz ktorý vás presmeruje na MDN Web Docs kde je k tomo ďalšia kopa (detailnejších) informácií... Celý kód je v jednom súbore (aj CSS, aj JS scripty v jednom html) aby bolo možné si ho jednoducho prekopírovať do svojho editora a ďalej s ním pracovať a skúšať si prípadne svoje úpravy v kóde. Myslím že pre začiatočníkov to bude fajn pomôcka...
Dobrý prehľad k "flex"-u je aj tu: css-tricks.com a samozrejme nemôže chýbať skvelá pomôcka na test, že či už ste to pochopili - flexfroggy.

Ak potrebujete len narýchlo naladiť dajaký konkétny obsah, a treba na to len zistiť pár príkazov z flex-u, tak netreba lúskať celý tento článok. Stačí skočiť na nasledujúci odkaz a tam sa dá na pár klikov nasimulovať "problém", "naklikať požiadavky" ako to má fungovať a stránka sama vygeneruje celý CSS kód ktorý stačí skopírovať a použiť:
Flex - rýchla pomôcka!

    "Majte na pamäti že správny výsledok layoutu stránky získate až správnou kombináciou tu predstavených jednotlivých možností!!!"

Čo je flex a na čo je to dobré pri tvorbe webu

Flex slúži na jednoduchšie pozíciovanie viacerých blokov v kontajneri, alebo na jednoduchšie pozíciovanie obsahu v samotnom bloku na stránke. Jeho silná stránka je upratovanie elementov vodorovne vedľa seba umiestnených na stránke. Ale samozrejme aj zvislo, podľa nastavení "direction", takže presnejšie povedané - v jednej línii. Myslím že z príkladov tu ďalej bude všetko jasné. Veľká pomoc flex-u je aj v centrovaní napríklad, a to ako vodorovnom (čo zvláda aj bežné CSS) tak aj zvislom (to je komplikovanejšie pre CSS), ale aj v ladení rozostupov medzi elementami v bloku - robí to automaticky a elegantne. Pár príkazov a všetko je razom nastavené. Zrovna tak aj responzivita sa ľahko rieši. A dokáže aj preusporiadať radenie elementov, čo by bolo inak naozaj dosť komplikované bez flex-u. Aj na to tu je ukážka.

Zobrazme si 3 základné bloky rozdielnej výšky s ktorými budeme najčastejšie ďalej pracovať...

Jednoducho sa zobrazia pod seba, lebo sú to blokové elementy, a na ľavý kraj stránky...

Aby fungoval flex, tak samozrejme musia byť v kontajneri ktorý ich obaľuje... A stačí jednoduchý príkaz "display: flex;" (pre kontajner ktorý ich obaľuje) a výsledok je úplne iný...
Zobrazia sa vedľa seba a s výškou rovnakou ako má najväčší blok. Rozhodne to hneď vyzerá "inak" na stránke.
(podmienka tohoto roztiahnutia je aby nemali výšku definovanú "na pevno"... V tomto prípade majú iba min-height pre rozdielnosť zobrazenia, ak nebudú mať definovanú žiadnu tak všetky dostanú rovnakú - najmenšiu potrebnú).

Klikni na jednotlivé príkazy aby bolo vidno ako sa mení zobrazenie:


1
2
3

Základné zoradenie blokov

Ale samozrejme flex dokáže fungovať aj v zvislom rozložení ak treba, a nie len to. Dokonca môže byť "zoradenie" tých blokov aj v opačnom poradí.
Ide to pomocou príkazu "flex-direction: parameter;"
Mimochodom - (ako to je aj vidno) zvislo sa tie výšky už nevyrovnávajú automaticky, pozor na to. A to ani keď sa definujú vlastnosti elementov pomocou flex: parameter;! Tie sa prejavia teraz iba vodorovne a ovplyvňovali by šírky elementov. Aj príkazy pre zoradenie (nasldujúce ukážky) budú pri zmene flex-direction fungovať opačne. Respektíve oni fungujú stále rovnako, ale mení sa hlavná os podľa ktorej potom fungujú...
Tu sú na to príklady:

Klikni na jednotlivé príkazy aby bolo vidno ako sa mení zobrazenie:





1
2
3

Správanie sa blokov v kontajneri

Ak tých blokov je viac, tak sa nastavuje aj to ako sa majú správať ak "nevojdú" do kontajnera (napríklad pri minimálnych šírkach v pixeloch, či v percentách, v podstate sa hneď vyrieši čiastočne responzivita webu...). Na to slúži príkaz flex-wrap: parameter;.
V základe sa natlačia tie bloky za každú cenu vedľa seba, čo ale môže byť v praxi riziko, a teda nežiadúce. Ako vidno snažia sa byť proporčne široké, ale keď sa pozrieme na percentá šírky ktorú majú dosahovať, tak to teda "nepasuje". Napraví sa to práve týmto príkazom. Elementy dostanú potom šírku v % (alebo iných jednotkách) presne ako majú definovanú.
Využitie to má napríklad pri tvorbe galérie - viac malých obrázkov rovnakej šírky. Zadáte si že majú mať šírku dajme tomu ako tu 23% (+ 1 a 1% sú margin, takže je to brané ako 4x25% v tomto prípade, aj minimálne dajme tomu dajaké pixely aby sa to moc nezcvrkávalo ten obsah sa oplatia nastaviť), vhodne to nastavíte príkazmi s medzerami okolo a už ich len hádžete za sebou, flex to "uprace" presne tak ako je vidno pri poslednej voľbe, kde sa po zmene ešte centrujú pomocou príkazu justify-content: space-between; (je o ňom hneď ďalšia kapitola). Blok s 80 % dostal ešte príkaz margin-left a margin-right "auto", aby sa nacentroval.
Pre lepšiu názornosť správania sa blokov po tomto príkaze majú tie hore aj rozdielnu šírku, a tie dolu rovnakú.
POZOR - toto je časť stránky ktorá na daktorých mobiloch s extra nízkym rozlíšením (pod 360px a zobrazenie na výšku) nebude možno zobrazená korektne. Ale na bežných funguje už korektne.

Klikni pre jednotlivé možnosti aby bolo vidno ako to v praxi funguje:



1 - 50 %
2 - 40 %
3 - 30 %
4 - 30 %
5 - 30 %
6 - 80 %

1
2
3
4
5
6
7

Základné usporiadanie blokov na šírku

A môže začať kúzlenie s týmito blokmi, respektíve s ich rozložením v kontajneri...
Pre názornosť výsledku sú v hlavnom bloku zakreslené osi x a y ktoré sú (dúfam) presne v strede bloku.
Posúvanie blokov vodorovne (usporiadanie na šírku) - to má na starosti príkaz justify-content: parameter;.
(pre výsledok klikni na požadovaný príkaz a rozloženie sa zmení)







1
2
3
X
 Y

Ako nastaviť potrebné (rozdielne) šírky blokov

Teraz sa pozrieme na to ako sa dá rozložiť obsah troch blokov na šírku ak potrebujeme ich rozdielnu šírku. To treba definovať priamo vo vlastnostiach tých blokov už. Dám sem zopár príkladov ako sa to zobrazí... Možnosti použitia jednotiek sú podobné ako pri definovaní širky elementu napríklad. (pixel , %, atď., ale aj iné, špecifické práve pre flex) Aj tie vlastnosti pri responzivite sú potom také podobné (pixely sú stabilne široké a podobne - tento blok má automatickú zmenu šírky, aby to bolo vidno ako to potom vlastne responzívne funguje). Tu ešte pozor na kombináciu s ostatnými príkazmi, hlavne wrap, nowrap, space medzi blokmi a podobne. Toto zobrazenie tu platí pre nowrap a žiadne riešenie space príkazom.
Pozor na hodnotu auto (v tomto prípade), ona urobí iba minimálne potrebnú šírku (pre obsah) elementu! Ak chceme využit zostávajúce miesto naplno, tak (v tomto prípade) treba použiť (napríklad) príkaz flex-grow:1;, oba príklady tu sú zobrazené.
Na pomerové delenie blokov ide použiť aj špecifický flex príkaz: flex: číselná hodnota; , príklad na to je úplne posledný.


(základné zobrazenie - takže sú tie 20% bloky pekne vedľa seba a vľavo)





1
2
3

Základné usporiadanie blokov na výšku

A ďalej tu máme usporiadanie blokov zvislo (na výšku) - to má na starosti príkaz align-items: parameter;.
POZOR - toto je iba centrovanie vzhľadom k ostatným blokom - výšku určuje (v tomto prípade) najvyšší blok. Ešte máme iné zvislé centrovanie - celého obsahu, to nasleduje hneď po tomto diely. Toto je veľmi žiadúce napríklad ak máte vedľa seba viaceré malé bloky textu s rozdielnou veľkosťou a teda aj výškou a potrebujete ich dostať "do dajakej línie" aby to lepšie vyzeralo...
(pre výsledok klikni na požadovaný príkaz a rozloženie sa zmení)





1
2
3
X
 Y

Usporiadanie obsahu kontajnera na výšku

Ďalšie pozíciovanie blokov zvislo (na výšku) - toto má na starosti príkaz align-content: parameter;.
A ako názov príkazu napovedá - toto je ladenie celého obsahu ku výške bloku. Na jeho fungovanie musí byť definovaná dajaká (väčšia) výška kontajnera. A má v podstate podobné možnosti ako mal príkaz "justify-content". Nie je tu úplne všetko, ešte by sa dalo napríklad toto:
align-content: baseline; align-content: first baseline; align-content: last baseline;
(pre výsledok klikni na požadovaný príkaz a rozloženie sa zmení)




1 - 50%
2 - 50%
3 - 100%
X

Ladíme jednotlivé bloky na výšku

A ďalej tu máme pozíciovanie jednotlivých! blokov zvislo (na výšku) - to má na starosti príkaz align-self: parameter;.
Príkaz je v podstate totožný s príkazom "align-items", akurát ovláda iba konkrétny jeden blok, a aj sa zadáva do toho konkrétneho bloku samozrejme, nie do kontajnera. Dám sem iba dajaké príklady čo to dokáže...
(pre výsledok klikni na požadovaný príkaz a rozloženie sa zmení)




1
2
3
X
 Y

Responzívny web pomocou flex - ukážka

Ešte sa hodí vedieť že máte aj možnosť preusporiadať postupnosť týchto blokov - to má na starosti príkaz order: číslo;.
V praxi sa to môže hodiť práve pri responzivite - na mobile iné usporiadanie ako na PC. Ukážem tu na príklade.
(Keďže mám aj margin 1% tak šírka každého elementu musí byť v kóde -2 percentá!)
(pre výsledok klikni na požadovaný príkaz a rozloženie sa zmení)




Menu
Main
Aside

A ešte ukážka responzivity pri zložitejšej stránke, aby bolo vidieť možnosti flexu "naplno". Aj keď - na toto sa hodí už viac grid... Ale aj flex to zvládne ak nie je treba dajako extra ladiť stránku čo sa týka "riadkov" - teda výšok elementov. Aj tu sa mení aj poradie blokov (pomocou order).
(pre výsledok klikni na požadovaný príkaz a rozloženie sa zmení)




Header
Menu
Main
Aside

Ladíme vnútorný obsah blokov

A ešte posledná ukážka, ako upratať obsah v tých blokoch... No ide to taktiež pomocou flex-u samozrejme. Aj tie blokové elementy dostanú vlastnosť display:flex; a s obsahom v nich sa potom dá narábať tak isto ako sme narábali s blokmi v kontajneri...
Ale POZOR - jednotlivé elementy musia občas byť vo vlastných blokoch - divoch, podľa toho ako s nimi potrebujete manipulovať! A ak to vyžaduje dizajn tak sa treba pohrať aj s nastavením šírky tých elementov.
Príkazy na to sú: justify-content: parameter; (posun vodorovne) a align-items: parameter; (posun zvislo). Parametre sú rovnaké ako platili pri blokoch.
Tu nechám na ukážku len príklady priamo v blokoch ako to v praxi bude vyzerať, myslím že je to jasné. Možností kombinovania tých príkazov, blokov v blokoch a podobne sú neskutočné...

1. blok dostal príkazy - display:flex; justify-content: center; align-items: flex-start;
(a celý obsah je v jednom kontajneri (ohraničenie), takže celý je pri sebe a hore v strede, ale pozor na jeho celkovú šírku, aj tú treba "nastaviť" ak má byť kvôli dizajnu dajaká konkrétna, inak bude 100%...)
2. blok dostal príkazy - display:flex; justify-content: flex-end; align-items: flex-end;
(a celý obsah je v jednom kontajneri, takže celý je pri sebe a vpravo dolu)
3. blok dostal príkazy - display:flex; justify-content: center; align-items: center;
(a celý obsah je v jednom kontajneri, takže celý je pri sebe a v strede)
A teraz trochu zložitejšie upratanie:
4. obsah už nie je v jednom div kontajneri, takže tie jednotlivé blokové elementy treba upratať inak... Je treba viaceré príkazy. display: flex; flex-direction: column; (usporiadaj obsah pod seba - POZOR - menia sa osi x a y pre pozíciovanie!!!), takže potom align-items: center; (obsah na stred po osi x) a justify-content: space-evenly; (roztiahni ho na výšku rovnomerne)
5. obdobne ako pri 4, len inak upratané - display: flex; flex-direction: column; align-items: flex-end; (obsah na koniec - vpravo) a justify-content: space-between; (roztiahni ho na výšku čo najviac od seba)

1
Nadpis
Obsah bloku
2
Nadpis
Obsah bloku
3
Nadpis
Obsah bloku
4
Nadpis
Obsah bloku
5
Nadpis
Obsah

Medzery medzi blokmi - gap / margin

Len tak pre zaujímavosť - na ladenie medzier medzi blokmi ide použiť aj príkaz "gap", známy skôr z "grid"-u. Tu funguje taktiež a netreba nastavovať marginy medzi elementami vo vnútri flex kontajnera. A ako to presne funguje vidno tu na príklade (presne takto sa to ale správa aj pri tom spomenutom grid-e). Všetky vnútorné elementy majú zrušené marginy, vonkajší obal má zrušené paddingy, a výsledok je takýto - po okrajoch je obsah v obale nalepený na obal, ale medzi sebou majú tie vnútorné bloky medzery - tu konkrétne 10px som nastavil pomocou "column-gap: 10px;" pre medzery medzi blokmi vedľa seba, a 20px pomocou "row-gap: 20px;" pre medzery medzi riadkami blokov (parametre sú zadané v obaľovacom elemente!). Medzeru medzi obalom a vnútornými elementami by som urobil pomocou padding-u pre obal (tak ako to mám všade inde v tomto kóde). Ide použiť aj čisto príkaz "gap: hodnota;", potom to platí pre medzery vodorovne aj zvislo. Ale mám pocit že pomocou marginov to je lepšie nastavovať... Možno sa občas hodí jedno, občas druhé, záleží asi na okolnostiach.

(POZOR na nastavené šírky elementov, ten gap sa k nim musí pripočítať, aby ešte vošli do obalu správne! V mojom kóde je to vidno ako som to doladil pomocou calc funkcie... Keďže mám nastavené pre obal "flex-wrap: wrap;", tak musím dávať pozor na šírky tých vnútorných elementov, lebo mi elementy hodí pod seba ak sa nevojdú.)

No a či a hlavne ako to funguje v praxi som skúsil napríklad tu: FlexBoxTest .
Ak chcete vidieť kód, prípadne sa s ním pohrať, tak je viditeľný aj na Codepen. Stránka je plne responzívna (mení sa aj poradie blokov), pohrajte sa s jej šírkou. Sú tam aj ukážky (výškového!) centrovania obsahu v blokoch (To funguje iba na PC, keď je obsah blokov vedľa seba! To je to obmedzenie flex-u oproti gridu...).

© Daniel Gago (2021)