Veronika Pavlíková PhD Student and Software Developer

CSS Flexible Box

Na dnešním cvičení se podíváme na tvorbu layoutu webové stránky pomocí CSS Flexboxu. Zopakujeme si, jak flex vytvořit a ukážeme si nejčastější příklady použití. Srovnáme ho s gridem a prodiskutujeme, kdy se hodí použití jednoho a kdy naopak druhého.

CSS Flexbox

CSS Flexible Box je specifikace (sada vlasností), která umožňuje tvořit layout pomocí jednodimenzionálního uspořádání prvků. Element, ve kterém takto prvky uspořádáme, se nazývá flex kontejner. Prvky v tomto kontejneru nazýváme flex items.

Vytvoření mřížky

Flex kontejner vytvoříme jednoduše: vybereme kontejner a nastavíme mu vlastnost display na hodnotu flex (případně inline-flex). Narozdíl od gridu zde nemusíme specifikovat přesný počet sloupců (nebo řádků), které chceme vytvořit. Prvky se automaticky naskládají podél hlavní osy. Jediné, co musíme specifikovat je, jestli chceme prvky umístit do sloupce nebo do řádku.

.box {
    display: flex;
    flex-direction: row;
}

Takto jsme vytvořili kontejner, ve kterém jsou prvky umístěny do jednoho řádku vedle sebe. Pokud bychom chtěli prvky umístit pod sebe, stačí místo hodnot row použít hodnotu column. K oběma hodnotám lze přidat sufix -reverse, který zajistí opačné vykreslení.

Zalamování prvků

Často se dostaneme do situace, kdy se prvky nevejdou na jeden řádek rodičovského elementu a začnou přetékat (pokud mají vlastnost flex-shrink nastavenou na 0) nebo se zmenšovat (pokud je flex-shrink nenulový). Tuto situaci lze řešit pomocí vlastnosti flex-wrap, která určuje, zda se prvky zobrazí pouze na jednom řádku (i za cenu přetečení), nebo zda se automaticky zalomí na další řádky. Tato vlastnost může nabývat následujících hodnot:

Stejná logika platí i pro zobrazení ve sloupci.

Směr flex kontejneru společně se zalamováním lze nastavit v jedné

Zarovnání obsahu

Při práci s flexboxem často potřebujeme ovlivnit nejen směr rozmístění prvků v kontejneru, ale také jejich zarovnání. Flexbox proto nabízí nástroje pro zarovnání jak na hlavní ose, tak na ose vedlejší.

Hlavní osa

Zarovnání na hlavní ose se nastavuje pomocí vlastnosti justify-content. Ta určuje, jak se rozdělí volné místo mezi prvky. Mezi nejčastější hodnoty patří flex-start (obsah je na začátku), flex-end (na konci), center (uprostřed), space-between (mezery pouze mezi prvky) a space-evenly (rovnoměrné rozestupy).

.box {
    display: flex;
    flex-flow: row wrap;
    justify-content: space-between;
}

Vedlejší osa

Na příčné ose můžeme zarovnávat obsah pomocí vlastnosti align-content. Ta určuje, jak se rozloží obsah uvnitř kontejneru (pokud je k dispozici volné místo). Mezi nejčastější hodnoty patří flex-start (obsah je zarovnán na začátek), flex-end (ke konci), center (na střed), space-between (mezery mezi prvky), a strech (roztažení obsahu). Tato vlastnost se používá například tehdy, když máme více řádků v jednom kontejneru a chceme ovlivnit jejich rozložení.

.box {
    display: flex;
    flex-flow: row wrap;
    align-content: center;
}

Typickým příkladem může být horizontální navigace, kde chceme mít jednotlivé položky rovnoměrně rozložené po šířce a zároveň je zarovnat na střed podle příčné osy. Představme si, že chceme na stránce udělat horizontální navigaci, podobnou jako je na této stránce. Jak byste to s Vašimi znalostmi nyní udělali?

Zarovnání položek

Kromě zarovnání celého obsahu se nám může hodit i zarovnání položek v kontejneru. Toto zarovnání už ale nastavujeme pouze u vedlejší osy (proč?).

Na příčné ose můžeme prvky zarovnat položky kontejneru pomocí vlastnosti align-items. Podobně jako u zarovnání obsahu nabývá i tato vlastnost hodnot flex-start, flex-end, center, strech a baseline.

Jaký je rozdíl mezi align-content a align-items? U contentu zarovnáváme celý obsah v rámci kontejneru (to může být více řádků nebo sloupců). U items zarovnáváme položky v rámci jednoho řádku (sloupce) v celém kontejneru.

Opět, kdy se nám toto bude hodit? Třeba pokud chceme udělat nějakou galerii fotek. Fotky mohou být různě vysoké a na stránce zobrazené v několika řádcích pod sebou. Fotky budou horizontálně rovnoměrně rozmístěné. Vertikálně je budeme chtít také rovnoměrně rozmístit. Zároveň ale chceme fotografie v každém řádku zarovnat na střed. Jak na to?

Zarovnání jedné položky

Někdy se nám může hodit zarovnat i jedinou položku podle vedlejší osy. K tomu slouží vlastnost align-self. Tohle se nám bude hodit obzvlášť pokud budou položky na ose různě veliké.

Roztažení položky (nastavení velikosti)

Doposud jsme si ukazovali vytvoření flexboxu, ve kterém byly všechny položky ve výchozím stavu stejně veliké (pokud jsme jim explicitně nenastavili velikost). Pokud jsme nespecifikovali jinak, tak všechny flex itemy zabíraly pouze takovou velikost jakou potřebovaly. Někdy se nám ale může hodit říci položce, kolik dostupného místa má zabírat. K tomu slouží vlastnosti flex-grow, flex-shrink, flex-basis a jejich kombinace flex.

flex-grow

Určuje, jak moc se má prvek zvětšovat, pokud je v kontejneru volné místo. Hodnota je relativní vůči ostatním prvkům – prvek s flex-grow: 2; dostane dvakrát více volného prostoru než prvek s flex-grow: 1;. Používá se tehdy, když chceme, aby se prvky dynamicky roztahovaly a vyplnily dostupné místo (např. layout, kde jeden blok má být větší než ostatní). POZOR! Neznamená to, že prvek s flex-grow: 2; bude dvakrát větší než ostatní prvky.

flex-shrink

Určuje, jak moc se má prvek zmenšovat, pokud se všechny prvky nevejdou do kontejneru. Opět jde o relativní hodnotu – prvek s vyšší hodnotou se zmenší více než ostatní. Výchozí hodnota je 1, takže prvky se standardně zmenšují, aby nepřetékaly. Používá se například v situacích, kdy chceme některým prvkům zabránit ve zmenšování (flex-shrink: 0).

flex-basis

Určuje základní (výchozí) velikost prvku před tím, než se začne uplatňovat flex-grow nebo flex-shrink. Lze ji chápat jako počáteční šířku nebo výšku (podle směru osy). Může mít hodnotu v pixelech, procentech nebo třeba auto. Používá se tehdy, když chceme určit výchozí velikost prvků, od které se pak odvíjí jejich další přizpůsobení v rámci flexboxu.

flex

Kombinovat předchozí vlastnosti nám umožňuje vlastnost flex. Nastavuje tedy flex-grow, flex-shrink a flex-basis v tomto pořadí. Pokud tedy napíšeme následující pravidlo:

.flex__item {
    flex: 0 1 200px;
}

znamená to, že nechceme, aby se prvek zvětšoval, může se ale zmenšit a jeho výchozí velikost bude 200px. Tento zápis je často ale zbytečně dlouhý. Pro zlepšení čitelnosti nám slouží zkratky, nejdůležitější jsou pro nás flex: auto pro plně pružnou položku (1 1 auto) a flex: číslo pro přesné nastavení šířky položky (číslo 1 0).

Na zopakování a upevnění znalostí si zahrajeme další hru na CSS Flexbox. Zkuste si udělat několik úrovní.

Odkaz na dobrovolné úkoly k dnešnímu cvičení.