CSS Layouty

Flexbox Layouty

V tomto článku se dozvíte vše o flexboxu. Najdete tu vysvětlení základních pojmů a všech vlastností, které se flexboxu týkají.

Co je to Flexbox

Flexbox představuje efektivnější způsob, jak v CSS vytvářet layouty. Hlavní myšlenka flexboxu je dát containeru (elementu obsahující další elementy) schopnost měnit šířku/výšku svých položek k co nejlepšímu využití místa. Flexbox umí své položky roztáhnout aby pokryly volné místo nebo naopak zmenšit aby nedošlo k přetečení. S jeho pomocí je tvorba layoutů mnohem jednodušší.

Terminologie

Vzhledem k tomu, že flexbox nepředstavuje jen jednu CSS vlastnost ale zahrnuje celou řadu vlastností, je tu pár věcí, které bychom měli před jejich prozkoumáním chápat. Flexbox zahrnuje pár pojmů, které jsou popsány v následující ukázce a v textu pod ní.

flex item
flex item
flex container
main axis
cross axis

flex container

Element, kterému nastavíme vlastnost display na "flex" se stává containerem a můžeme do něj přidávat elementy (itemy).

flex item

Element, který přidáme do flex containeru se nazývá item. Já ho v tomto článku budu označovat jako položka.

Main axis

Hlavní osa představuje směr, ve kterém se za sebe řadí položky v containeru. Defaultně se položky řadí zleva doprava, ale tento směr se dá změnit pomocí vlastnosti flex-direction. V tomto článku budu hlavní osu označovat jako osa main.

Cross axis

Na příčné ose definujeme jak se budou položky v containeru zarovnávat. Defaultně se položky roztahují od jednoho okraje k druhému. Můžeme to ale změnit pomocí vlastnosti align-items. V tomto článku budu příčnou osu označovat jako osa cross.

Vytvoření flex containeru

Flex container vytvoříme tak, že elementu, který chceme aby byl container nastavíme display vlastnost na flex, popřípadě inline-flex. Rozdíl mezi hodnotou flex a inline-flex je ten, že při nastavení hodnoty na inline-flex bude container inline element a při nastavení hodnoty na flex bude container block element. Je třeba dodat že při použití inline-flex bude jen container inline element, jeho položky ne.

<!DOCTYPE html>
<html lang="cs">
<head>
    <title>Vytvoření flex containeru</title>
    <style>
        .flex-container {
            displayflex;
            background-colorlightgreen;
        }
        .inline-flex-container {
            displayinline-flex;
            background-colorlightgreen;
        }
    </style>
</head>
<body>
    Toto je <div class="flex-container">flex</div> container.
    <hr>
    Toto je <div class="inline-flex-container>inline-flex</div> container.
</body>
</html>
Toto je
flex
container.

Toto je
inline-flex
container.

Vlastnosti containeru a jeho položek

Některé vlastnosti týkající se flexboxu se nastavují na container a některé na jeho položky. Vlastnosti které se nastavují na container jsou: flex-direction, flex-wrap, flex-flow, justify-content, align-items a align-content. Vlastnosti, které se nastavují na položky containeru jsou: order, flex-grow, flex-shrink, flex-basis, flex a align-self. Zbytek článku se zaměřuje na jednotlivé vlastnosti.

flex-direction

Tato vlastnost mění směr osy main. Jejím změněním tedy určíme jakým směrem se za sebe budou položky v containeru řadit.

Hodnoty, které můžeme nastavit:

  • row (defaultní): položky se řadí zleva doprava
  • row-reverse: položky se řadí zprava doleva
  • column: položky se řadí shora dolů
  • column-reverse: položky se řadí zdola nahoru
.container {
    displayflex;
    background-colorlightgreen;
    margin10px;
    padding5px;

    flex-directioncolumn/* změna směru osy main */
}

.item {
    background-colororangered;
    border2px solid green;
    width60px;
    height60px;
    font-size16px;
}
<!DOCTYPE html>
<html>
<head>
    <title>flex-direction</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <div class="item">1</div>
        <div class="item">2</div>
        <div class="item">3</div>
        <div class="item">4</div>
    </div>
</body>
</html>
1
2
3
4

flex-wrap

Defaultně se budou položky v containeru snažit vlézt na jeden řádek. To ale můžeme změnit a umožnit položkám při nedostatku místa pokračovat na dalším řádku. Uděláme to nastavením vlastnosti flex-wrap na hodnotu wrap nebo wrap-reverse.

Hodnoty, které můžeme nastavit:

  • nowrap (defaultní): všechny položky budou na jednom řádku
  • wrap: při nedostatku místa budou položky pokračovat na dalších řádcích shora dolů
  • wrap-reverse: při nedostatku místa budou položky pokračovat na dalších řádcích zdola nahoru (řádky budou přibývat nahoře)
.container {
    displayflex;
    background-colorlightgreen;
    margin10px auto;
    padding5px;

    width400px;
    flex-wrapwrap/* při nedostatku místa budou položky pokračovat na dalším řádku */
}

.item {
    background-colororangered;
    border2px solid green;
    width: 60px;
    height60px;
    font-size16px;
}
<!DOCTYPE html>
<html>
<head>
    <title>flex-wrap</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <div class="item">1</div>
        <div class="item">2</div>
        <div class="item">3</div>
        <div class="item">4</div>
        <div class="item">5</div>
        <div class="item">6</div>
        <div class="item">7</div>
        <div class="item">8</div>
        <div class="item">9</div>
    </div>
</body>
</html>
1
2
3
4
5
6
7
8
9

flex-flow

Tato vlastnost je zkratkou pro vlastnosti flex-direction a flex-wrap. Můžeme je tedy pomocí této vlastnosti nastavit zároveň.

.container {
    displayflex;
    background-colorlightgreen;
    margin10px;
    padding5px;
    height200px;

    flex-flowcolumn wrap;  /* zkratka pro flex-direction a flex-wrap */
}

.item {
    background-colororangered;
    border2px solid green;
    width: 60px;
    height60px;
    font-size16px;
}
<!DOCTYPE html>
<html>
<head>
    <title>flex-flow</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <div class="item">1</div>
        <div class="item">2</div>
        <div class="item">3</div>
        <div class="item">4</div>
        <div class="item">5</div>
        <div class="item">6</div>
        <div class="item">7</div>
        <div class="item">8</div>
        <div class="item">9</div>
    </div>
</body>
</html>
1
2
3
4
5
6
7
8
9

justify-content

Tato vlastnost určuje, jak se položky v containeru zarovnají na ose main. Pokud ji nastavíme například na hodnotu center, tak se položky zarovnají na střed.

Hodnoty, které můžeme nastavit:

  • flex-start (defaultní): položky se zarovnají na začátek osy main
  • flex-end: položky se zarovnají na konec osy main
  • start: položky se zarovnají na začátek writing-mode směru
  • end: položky se zarovnají na konec writing-mode směru
  • left: položky se zarovnají k levému okraji containeru, pokud to nedává smysl vzhledem k flex-direction, tak se tato hodnota chová stejně jako hodnota start
  • right: položky se zarovnají k pravému okraji containeru, pokud to nedává smysl vzhledem k flex-direction, tak se tato hodnota chová stejně jako hodnota end
  • center: položky se zarovnají na střed osy main
  • space-between: položky se rovnoměrně rozprostřou po celé ose main (před první a za poslední položkou nebude žádná mezera, jen mezi položkami)
  • space-around: položky se rovnoměrně rozprostřou po celé ose main, tak aby měly všechny položky nalevo a napravo stejnou mezeru (před první a za poslední položkou tedy bude menší mezera než jinde)
  • space-evenly: položky se rovnoměrně rozprostřou po celé ose main, tak aby mezery mezi položkami a na krajích osy main byly stejné
.container {
    displayflex;
    background-colorlightgreen;
    margin10px;
    padding5px;

    justify-contentspace-between/* zarovnání položek na ose main */
}

.item {
    background-colororangered;
    border2px solid green;
    width: 60px;
    height60px;
    font-size16px;
}
<!DOCTYPE html>
<html>
<head>
    <title>justify-content</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <div class="item">1</div>
        <div class="item">2</div>
        <div class="item">3</div>
        <div class="item">4</div>
    </div>
</body>
</html>
1
2
3
4

align-items

Tato vlastnost určuje, jak se položky v containeru zarovnají na ose cross. Pokud ji nastavíme například na hodnotu center, tak se položky zarovnají na střed.

Hodnoty, které můžeme nastavit:

  • stretch (defaultní): položky se roztáhnou od jednoho okraje containeru k druhému
  • flex-start / start / self-start: položky se zarovnají na začátek osy cross (rozdíl mezi těmito hodnotami je malý a týká se respektování flex-direction nebo writing-mode vlastnosti.)
  • flex-end / end / self-end: položky se zarovnají na konec osy cross (rozdíl mezi těmito hodnotami je malý a týká se respektování flex-direction nebo writing-mode vlastnosti.)
  • center: položky se zarovnají na střed osy cross
  • baseline: položky se zarovnají podle jejich textu
.container {
    displayflex;
    background-colorlightgreen;
    margin10px;
    padding5px;

    align-itemscenter; /* zarovnání položek na ose cross */
}

.item-1item-2item-3item-4 {
    background-colororangered;
    border2px solid green;
    width: 60px;
    font-size16px;
}

.item-1 height60px}
.item-2 height80px}
.item-3 height110px}
.item-4 height70px}
<!DOCTYPE html>
<html>
<head>
    <title>align-items</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <div class="item-1">1</div>
        <div class="item-2">2</div>
        <div class="item-3">3</div>
        <div class="item-4">4</div>
    </div>
</body>
</html>
1
2
3
4

align-content

Tato vlastnost se projeví ve víceřádkových containerech, protože určuje jak se zarovnají řádky pokud je v containeru ještě volné místo.

Hodnoty, které můžeme nastavit:

  • normal (defaultní): položky jsou zarovnány ve své defaultní pozici jako by žádná hodnota nebyla nastavena
  • flex-start / start: položky jsou zarovnány k začátku containeru (flex-start se týká flex-direction a start se týká writing-mode směru)
  • flex-end / end: položky jsou zarovnány ke konci containeru (flex-end se týká flex-direction a end se týká writing-mode směru)
  • center: položky se zarovnají na střed containeru
  • space-between: položky se rovnoměrně rozprostřou (před prvním a za posledním řádkem nebude žádná mezera, jen mezi řádky)
  • space-around: položky se rovnoměrně rozprostřou, tak aby měly všechny řádky po svých stranách stejnou mezeru (před prvním a za posledním řádkem tedy bude menší mezera než jinde)
  • space-evenly: položky se rovnoměrně rozprostřou, tak aby mezery mezi řádky a na krajích containeru byly stejné
  • stretch: řádky se roztáhnou aby zabraly zbývající místo
.container {
    displayflex;
    background-colorlightgreen;
    margin10px auto;
    padding5px;
    width400px;
    height200px;

    flex-wrapwrap/* při nedostatku místa budou položky pokračovat na dalším řádku */
    align-contentspace-between/* zarovnání řádků v containeru */
}

.item {
    background-colororangered;
    border2px solid green;
    width60px;
    height60px;
    font-size16px;
}
<!DOCTYPE html>
<html>
<head>
    <title>align-content</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <div class="item">1</div>
        <div class="item">2</div>
        <div class="item">3</div>
        <div class="item">4</div>
        <div class="item">5</div>
        <div class="item">6</div>
        <div class="item">7</div>
        <div class="item">8</div>
        <div class="item">9</div>
    </div>
</body>
</html>
1
2
3
4
5
6
7
8
9

order

Defaultně se položky v containeru řadí podle toho jak je zapíšeme v HTML. To ale můžeme změnit pomocí vlastnosti order. Tuto vlastnost nastavujeme na položky containeru a jako hodnotu předávame číslo, které určuje na jakém místě se položka zobrazí. Položky se řadí od nejmenšího čísla po největší. Defaultní hodnota vlastnosti order je 0.

.container {
    displayflex;
    background-colorlightgreen;
    margin10px;
    padding5px;
}

.item-1.item-2.item-3.item-4 {
    background-colororangered;
    border2px solid green;
    width60px;
    height60px;
    font-size16px;
}

.item-1 order3}
.item-2 order-2}
.item-3 order1}
<!DOCTYPE html>
<html>
<head>
    <title>order</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <div class="item-1">order: 3</div>
        <div class="item-2">order: -2</div>
        <div class="item-3">order: 1</div>
        <div class="item-4">order: 0</div>
    </div>
</body>
</html>
order: 3
order: -2
order: 1
order: 0

flex-grow

Tato vlastnost definuje schopnost položky v containeru růst. Jako hodnotu jí předáváme číslo, které určuje jak moc bude položka moci růst oproti ostatním položkám. Defaultní hodnota je 0 a znamená to že položka nebude moci růst vůbec.

Pokud budou mít všechny položky v containeru nastavenou vlastnost flex-grow například na hodnotu 1, tak se zbývající místo v containeru rozdělí položkám rovnoměrně. Pokud ale jedna z položek bude mít vlastnost flex-grow nastavenou na hodnotu 2, tak tato položka dostane dvakrát více místa než ostatní.

.container {
    displayflex;
    background-colorlightgreen;
    margin10px;
    padding5px;
}

.item.item-special {
    background-colororangered;
    border2px solid green;
    height60px;
    font-size16px;
    flex-grow1/* schopnost položky růst */
}

.item-special flex-grow: 2/* položka s touto třídou bude moci růst více než ostatní */
<!DOCTYPE html>
<html>
<head>
    <title>flex-grow</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <div class="item">1</div>
        <div class="item-special">2</div>
        <div class="item">3</div>
        <div class="item">4</div>
    </div>
</body>
</html>
1
2
3
4

flex-shrink

Tato vlastnost definuje schopnost položky v containeru se zmenšit když je to potřeba. Defaultní hodnota je 1, což znamená že se položka může zmenšit. Pokud bychom chtěli nastavit aby se položka nemohla zmenšit, museli bychom vlastnost flex-shrink nastavit na 0.

Podobně jako u vlastnosti flex-grow, pokud budou mít všechny položky v containeru nastavenou vlastnost flex-shrink například na hodnotu 1, budou se všechny zmenšovat stejně. Pokud ale jedna z položek bude mít vlastnost flex-shrink nastavenou například na hodnotu 2, tak se tato položka bude zmenšovat dvakrát víc než ostatní.

.container {
    displayflex;
    background-colorlightgreen;
    margin10px auto;
    padding5px;
    width190px/* container má menší šířku než všechy jeho položky */
}

.item.item-special {
    background-colororangered;
    border2px solid green;
    height60px;
    width60px;
    font-size16px;
    flex-shrink1/* schopnost položky zmenšovat se (nastavovat bychom to nemuseli, 1 je defaultní) */
}

.item-special flex-shrink: 2/* položka s touto třídou se bude moci zmenšovat více než ostatní */
<!DOCTYPE html>
<html>
<head>
    <title>flex-shrink</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <div class="item">1</div>
        <div class="item-special">2</div>
        <div class="item">3</div>
        <div class="item">4</div>
    </div>
</body>
</html>
1
2
3
4

flex-basis

Tato vlastnost definuje defaultní velikost položky v containeru než se rozdělí zbývající prostor. Jako hodnotu můžeme vlastnosti flex-basis předat délku (px, %, rem, atd..) nebo hodnotu auto, která je defaultní. Hodnota auto znamená, že se flex-basis nastaví podle šířky nebo výšky položky.

.container {
    displayflex;
    background-colorlightgreen;
    margin10px;
    padding5px;
}

.item.item-special {
    background-colororangered;
    border2px solid green;
    height60px;
    font-size16px;
}

/* položka s touto třídou obsadí před rozdělením zbývajícího místa 70 pixelů */
/* (zbývající místo se ale nerozdělí, protože je vlastnost flex-grow nastavena na 0) */
.item-special flex-basis: 70px}
<!DOCTYPE html>
<html>
<head>
    <title>flex-basis</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <div class="item">1</div>
        <div class="item-special">2</div>
        <div class="item">3</div>
        <div class="item">4</div>
    </div>
</body>
</html>
1
2
3
4

flex

Tato vlastnost je zkratkou pro vlastnosti flex-grow, flex-shrink a flex-basis. Můžeme tedy tyto vlastnosti nastavit všechny najednou. Druhá a třetí hodnota (flex-shrink a flex-basis) je ale volitelná, takže nemusíme nastavovat všechny tři pokud nechceme.

.container {
    displayflex;
    background-colorlightgreen;
    margin10px;
    padding5px;
}

.item {
    background-colororangered;
    border2px solid green;
    height60px;
    font-size16px;
    flex1 0 60px/* zkratka pro flex-grow, flex-shrink a flex-basis */
}
<!DOCTYPE html>
<html>
<head>
    <title>flex</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <div class="item">1</div>
        <div class="item">2</div>
        <div class="item">3</div>
        <div class="item">4</div>
    </div>
</body>
</html>
1
2
3
4

align-self

Tato vlastnost umožňuje položkám v containeru přepsat defaultní zarovnání na ose cross, které bylo na container nastaveno pomocí vlastnosti align-items. Pomocí vlastnosti align-self můžeme tedy nastavit zarovnání na ose cross jen pro nějaké položky v containeru a ne pro všechny.

Hodnoty, které můžeme nastavit:

  • stretch (defaultní): položka se roztáhne od jednoho okraje containeru k druhému
  • flex-start / start / self-start: položka se zarovná na začátek osy cross (rozdíl mezi těmito hodnotami je malý a týká se respektování flex-direction nebo writing-mode vlastnosti.)
  • flex-end / end / self-end: položka se zarovná na konec osy cross (rozdíl mezi těmito hodnotami je malý a týká se respektování flex-direction nebo writing-mode vlastnosti.)
  • center: položka se zarovná na střed osy cross
  • baseline: položka se zarovná podle textu
.container {
    displayflex;
    background-colorlightgreen;
    margin10px;
    padding5px;
    align-itemscenter/* zarovnání položek na ose cross */
}

.item-1item-2item-3item-4 {
    background-colororangered;
    border2px solid green;
    width60px;
    font-size16px;
}

.item-1 height60px}
.item-2 {
    height80px;
    align-selfflex-end/* přepsání vlastnosti align-items */
}
.item-3 { height110px}
.item-4 { height70px}
<!DOCTYPE html>
<html>
<head>
    <title>align-self</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <div class="item-1">1</div>
        <div class="item-2">2</div>
        <div class="item-3">3</div>
        <div class="item-4">4</div>
    </div>
</body>
</html>
1
2
3
4