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 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.
<html lang="cs">
<head>
<title>Vytvoření flex containeru</title>
<style>
.flex-container {
display: flex;
background-color: lightgreen;
}
.inline-flex-container {
display: inline-flex;
background-color: lightgreen;
}
</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>
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
display: flex;
background-color: lightgreen;
margin: 10px;
padding: 5px;
flex-direction: column; /* změna směru osy main */
}
.item {
background-color: orangered;
border: 2px solid green;
width: 60px;
height: 60px;
font-size: 16px;
}
<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>
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)
display: flex;
background-color: lightgreen;
margin: 10px auto;
padding: 5px;
width: 400px;
flex-wrap: wrap; /* při nedostatku místa budou položky pokračovat na dalším řádku */
}
.item {
background-color: orangered;
border: 2px solid green;
width: 60px;
height: 60px;
font-size: 16px;
}
<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>
flex-flow
Tato vlastnost je zkratkou pro vlastnosti flex-direction a flex-wrap. Můžeme je tedy pomocí této vlastnosti nastavit zároveň.
display: flex;
background-color: lightgreen;
margin: 10px;
padding: 5px;
height: 200px;
flex-flow: column wrap; /* zkratka pro flex-direction a flex-wrap */
}
.item {
background-color: orangered;
border: 2px solid green;
width: 60px;
height: 60px;
font-size: 16px;
}
<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>
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é
display: flex;
background-color: lightgreen;
margin: 10px;
padding: 5px;
justify-content: space-between; /* zarovnání položek na ose main */
}
.item {
background-color: orangered;
border: 2px solid green;
width: 60px;
height: 60px;
font-size: 16px;
}
<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>
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
display: flex;
background-color: lightgreen;
margin: 10px;
padding: 5px;
align-items: center; /* zarovnání položek na ose cross */
}
.item-1, item-2, item-3, item-4 {
background-color: orangered;
border: 2px solid green;
width: 60px;
font-size: 16px;
}
.item-1 { height: 60px; }
.item-2 { height: 80px; }
.item-3 { height: 110px; }
.item-4 { height: 70px; }
<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>
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
display: flex;
background-color: lightgreen;
margin: 10px auto;
padding: 5px;
width: 400px;
height: 200px;
flex-wrap: wrap; /* při nedostatku místa budou položky pokračovat na dalším řádku */
align-content: space-between; /* zarovnání řádků v containeru */
}
.item {
background-color: orangered;
border: 2px solid green;
width: 60px;
height: 60px;
font-size: 16px;
}
<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>
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.
display: flex;
background-color: lightgreen;
margin: 10px;
padding: 5px;
}
.item-1, .item-2, .item-3, .item-4 {
background-color: orangered;
border: 2px solid green;
width: 60px;
height: 60px;
font-size: 16px;
}
.item-1 { order: 3; }
.item-2 { order: -2; }
.item-3 { order: 1; }
<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>
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í.
display: flex;
background-color: lightgreen;
margin: 10px;
padding: 5px;
}
.item, .item-special {
background-color: orangered;
border: 2px solid green;
height: 60px;
font-size: 16px;
flex-grow: 1; /* schopnost položky růst */
}
.item-special { flex-grow: 2; } /* položka s touto třídou bude moci růst více než ostatní */
<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>
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í.
display: flex;
background-color: lightgreen;
margin: 10px auto;
padding: 5px;
width: 190px; /* container má menší šířku než všechy jeho položky */
}
.item, .item-special {
background-color: orangered;
border: 2px solid green;
height: 60px;
width: 60px;
font-size: 16px;
flex-shrink: 1; /* 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í */
<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>
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.
display: flex;
background-color: lightgreen;
margin: 10px;
padding: 5px;
}
.item, .item-special {
background-color: orangered;
border: 2px solid green;
height: 60px;
font-size: 16px;
}
/* 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; }
<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>
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.
display: flex;
background-color: lightgreen;
margin: 10px;
padding: 5px;
}
.item {
background-color: orangered;
border: 2px solid green;
height: 60px;
font-size: 16px;
flex: 1 0 60px; /* zkratka pro flex-grow, flex-shrink a flex-basis */
}
<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>
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
display: flex;
background-color: lightgreen;
margin: 10px;
padding: 5px;
align-items: center; /* zarovnání položek na ose cross */
}
.item-1, item-2, item-3, item-4 {
background-color: orangered;
border: 2px solid green;
width: 60px;
font-size: 16px;
}
.item-1 { height: 60px; }
.item-2 {
height: 80px;
align-self: flex-end; /* přepsání vlastnosti align-items */
}
.item-3 { height: 110px; }
.item-4 { height: 70px; }
<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>