☰ menu
Pavel Satrapa

Zapružíme, uvidíme – flexbox

Flexible box aneb flexbox umožňuje snadno řídit rozložení prvků v jednom směru – buď vedle sebe, nebo nad sebou. Typické využití najde třeba v záhlaví a zápatí stránky, kde rovnáte vedle sebe položky menu, ikony a podobně. Dříve se pro tento účel používaly různé triky s obtékáním, ovšem flexbox je jednodušší a předvídatelnější.

Obalující prvek

Vezměme si jako příklad jednoduché záhlaví fiktivního webu. Vlevo je logo, uprostřed položky hlavního menu, napravo přepínač jazyků:

o nás
služby
provozovny
kontakt
cs/en

HTML kód je velmi jednoduchý. Celé záhlaví je zabaleno do jednoho obalujícího prvku (zde <div class="zahlavi">, u skutečného záhlaví raději sémantický prvek <header>). Jeho děti představují jednotlivé položky záhlaví:

<div class="zahlavi">
    <div class="logo">&#x263b;</div>
    <div class="polozka">o nás</div>
    <div class="polozka">služby</div>
    <div class="polozka">provozovny</div>
    <div class="polozka">kontakt</div>
    <div class="jazyk"><strong>cs</strong>/en</div>
</div>

Flexbox vytvoříte tak, že obalujícímu prvku přiřadíte vlastnost display s hodnotou flex. Tím je položen základ, podobu pak doladíte pomocí vlastností obalujícího prvku a jeho dětí.

Zda budou děti ve flexboxu uspořádány vedle sebe nebo nad sebou určuje vlastnost flex-direction. Základními hodnotami jsou row (vedle sebe, výchozí hodnota) a column (nad sebou). Můžete také obrátit pořadí jeho dětí hodnotami row-reverse a column-reverse.

Pomocí justify-content určíte, jak mají být položky flexboxu rozmístěny ve směru jeho hlavní osy. Výchozí hodnota flex-start je umístí doleva (při svislém uspořádání od horního okraje), flex-end doprava (dolů) a center je vycentruje. Zajímavá je také možnost space-between, která rovnoměrně rozdělí volné místo mezi jednotlivé položky tak, aby zabraly celou velikost flexboxu:

o nás
služby
provozovny
kontakt
cs/en
o nás
služby
provozovny
kontakt
cs/en
o nás
služby
provozovny
kontakt
cs/en
o nás
služby
provozovny
kontakt
cs/en

Vlastnost align-items řídí zarovnání položek ve směru kolmém na hlavní osu flexboxu. Hodnota flex-start je zarovná k hornímu okraji (při svislém uspořádání k levému), flex-end ke spodnímu (doprava), center je vycentruje a výchozí stretch roztáhne na celou výšku (šířku) flexboxu. V příkladech výše je nastaveno align-items: center, protože logo je vyšší než textové položky.

A ještě jednu praktickou vlastnost jsem zatím zatajil: gap určuje velikost mezery mezi položkami. V ukázkách používám gap: 1rem. Je to jednodušší, než šachovat s margin a řešit výjimky pro první/poslední prvek.

Pokud hrozí, že by obsah flexboxu mohl být širší než dostupné místo, nasaďte flex-wrap: wrap, což dovolí, aby se obsah rozložil do několika řádků (sloupců). Takto dopadne úzký flexbox se zakázaným (výchozí hodnota nowrap) a povoleným (wrap) rozdělením do více řádků:

o nás
služby
provozovny
kontakt
cs/en
o nás
služby
provozovny
kontakt
cs/en

Společné nastavení všech příkladů, které tu vidíte, obsahuje:

.zahlavi {
    display: flex;
    gap: 1rem;
    align-items: center;
}

Děti

Vlastnosti obalujícího prvku určují celkové rozložení flexboxu a obecná pravidla, která v něm platí. Vlastnosti jeho dětí umožňují zavádět výjimky a řídit podobu konkrétních položek v jeho obsahu.

Začněme poněkud kontroverzní vlastností order, kterou lze měnit pořadí zobrazených prvků. Implicitně se dodržuje pořadí podle zdrojového kódu (případně se obrátí, pokud použijete některý ze směrů -reverse). Přesněji řečeno se prvky řadí vzestupně (sestupně pro -reverse) podle hodnot své vlastnosti order a pokud je stejná, zůstanou v původním pořadí. Hodnotou je celé číslo, výchozí je 0. Takže například přepínač jazyků jsem beze změny zdrojového kódu přesunul doleva přiřazením order: -1:

o nás
služby
provozovny
kontakt
cs/en

Kontroverze spočívá v tom, že při ovládání klávesnicí zaměření přesouvané klávesou Tab dodržuje pořadí podle zdrojového kódu. Takže pohyb v menu bude chaotický a zhoršuje přístupnost stránky. Nově pro řešení tohoto problému vznikla vlastnost reading-flow: flex-visual, ale její podpora je zatím (polovina roku 2025) v plenkách.

Důležitá sada individuálních vlastností řídí rozměry prvku ve směru hlavní osy flexboxu. Dále budu předpokládat, že je uspořádán vodorovně, proto budu mluvit o šířce prvků. Při svislém uspořádání se totéž týká výšky.

Výchozí šířku určuje flex-basis. Asi málokdy budete měnit výchozí hodnotu auto, ale ta možnost tu je. Například bych mohl logo poněkud odsadit od následujících prvků tím, že mu přiřadím flex-basis: 10%:

o nás
služby
provozovny
kontakt
cs/en

Zajímavější jsou vlastnosti flex-grow a flex-shrink, které rozhodují o tom, zda lze výchozí šířku prvku zvětšit a zmenšit. Hodnotou je celé číslo, které udává koeficient roztažnosti či stlačitelnosti. Je-li obsah flexboxu užší než rodičovský prvek, pak se prvky s nenulovým flex-grow roztáhnou tak, aby obsah zabral celou šířku. Dostupné místo si rozdělí v poměru podle svých koeficientů roztažnosti. Například nastavení flex-grow: 1 pro logo zařídí, že se logo roztáhne a následné menu bude de facto zarovnáno doprava:

o nás
služby
provozovny
kontakt
cs/en

Nastavím-li flex-grow: 1 i pro přepínač jazyků (a přidám pro něj zarovnání textu doprava), dostanu:

o nás
služby
provozovny
kontakt
cs/en

Výchozími hodnotami jsou flex-grow: 0 (prvky se neroztahují) a flex-shrink: 1 (lze je stlačit).

Chcete-li změnit polohu konkrétního prvku ve směru kolmo na směr flexboxu, použijte align-self. Hodnoty a významy jsou totožné s vlastností align-items. Například lze vyzdvihnout aktuálně vybranou položku menu přiřazením align-self: flex-start:

o nás
služby
provozovny
kontakt
cs/en

Kompletní přehled všech souvisejících vlastností najdete na stránce CSS Flexbox Layout Guide.