Podstawy flexbox

Poradnik CSS (z przykładem layoutu „mobile first”) dla tych, którzy mają już dość tworzenia layoutów przy użyciu float i margin. Flexbox pozwala na łatwe tworzenie layoutów, ułatwiając dodatkowo zmianę layoutu dla różnych urządzeń przez media queries.

Layout przy pomocy flexbox

Spis treści

  1. Co to jest ten flex, flexbox?
  2. Zaczynamy tworzyć layout przy użyciu flexbox
  3. Użycie flexbox do pokazania galerii
  4. Kilka słów na koniec

Co to jest ten flex, flexbox?

Flexbox (z ang. Flex Box, czyli Flexible Box) to jedna z wielu metod na tworzenie layoutu – zarówno strony, jak i poszczególnych elementów strony – który będzie elastyczny, tzn. będzie się dostosowywał do wymiarów ekranu. Pozwala w łatwy sposób utworzyć layout strony, oraz zmodyfikować go odpowiednio dla różnych wielkości ekranu. Dla tych którzy nie lubią podejścia mobile first, sprawdzi się równie dobrze w podejściu desktop first.

Dzięki flexbox unikniesz w wielu przypadkach dodatkowych wrapperów (<div class="wrapper">), aby jakieś elementy ułożyć obok siebie. Nie będą też potrzebne float’y, ujemne marginesy ani kombinowanie z nadawaniem wysokości elementom, aby dwa znajdujące się obok siebie były tak samo wysokie.

Czy flexbox nadaje się do każdego layoutu?

I tak i nie… W zasadzie każdy layout da się zaprojektować z użyciem flexbox, ale w celu uzyskania bardziej zaawansowanych potrzebne będą dodatkowe wrappery. Przy takich być może lepszą opcją będzie layout oparty o CSS grid.

Zaczynamy tworzyć layout przy użyciu flexbox

Powiedzmy, że chcemy stworzyć tradycyjny layout z nagłówkiem, menu, stopką, treścią właściwą i jakimś sidebarem. W dużym skrócie, html zrobimy taki:

<body>
  <header>Nagłówek</header>
  <article>Jakaś treść właściwa</article>
  <aside>Panel boczny</aside>
  <nav>Nawigacja</nav>
  <footer>Stopka</footer>
</body>

Kolejność nie jest przypadkowa – nawigacja celowo jest nisko, żeby jej zawartość nie była pierwszą treścią na stronie – dzięki temu w wynikach wyszukiwarek nie pojawi się kawałek menu, tylko treść właściwa ze strony. Dla wyższych rozdzielczości ekranu przeniesiemy ją łatwo nad treść właściwą.

Layout na najmniejsze rozdzielczości ekranu, czyli telefony komórkowe

Teraz dodajmy jakieś proste stylowanie + ustawmy odpowiednią kolejność, aby strona jakoś wyglądała – dla telefonów może to być wersja jeden bloczek pod drugim. Zatem nasz CSS będzie wyglądał tak:

body {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin: 0;
padding: 0;
}
body > * {
flex-basis: 100%;
margin: 0;
padding: 1em 2em;
box-sizing: border-box;
}
header {
background: green;
}
nav {
background: yellow;
}
article {
background: cyan;
}
aside {
background: pink;
}
footer {
background: red;
}

Nasz layout powinien wyglądać tak:

Flexbox dla smartfonów

Teraz kilka słów wyjaśnienia:

Zatem mamy prosty layout, nadający się na telefony komórkowe – każdy element jest na pełną szerokość strony, kolejność jest taka jak w HTMLu.

Modyfikacje layoutu dla większych rozdzielczości, jak np. tablety

Powiedzmy że dla większych rozdzielczości (od 768px) chcemy, aby menu pojawiło się na górze, a panel boczny aby się zmieścił obok treści głównej. Dodajemy zatem CSS przy użyciu media queries

@media only screen and (min-width:768px) {
header {
order: 1;
}
nav {
order: 2;
}
article {
order: 3;
flex-basis: 70%;
}
aside {
order: 4;
flex-basis: 30%;
}
footer {
order: 5;
}
}

Teraz nasz layout powinien wyglądać tak jak na poniższym obrazku

Flexbox dla tabletu

I ponownie kilka słów wyjaśnienia:

Krótkie podsumowanie parametrów flexbox

Nazwa parametru Opis Przykładowe wartości Gdzie ustawiany
display Ustawia sposób renderowania elementów wewnątrz danego taga flex kontener
flex-direction Określa w którą stronę (w pionie lub poziomie) będą ukłądane kolejne elementy wewnątrz kontenera row, row-reverse, column, column-reverse kontener
flex-wrap Określa, czy elementy mogą przechodzić do kolejnych wierszy nowrap, wrap, wrap-reverse element
flex-basis Ustawia szerokość (względną lub bezwzględną) dla danego elementu w kontenerze. 100%, 50px, auto element
order Umożliwia zmianę kolejności wyświetlania elementów flexboksa element
flex-grow Umożliwia rozszerzenie elementu, jeśli jest na to miejsce 0 (domyślnie), 1 element
flex-shrink Umożliwia zmniejszenie elementu, aby wiele zmieściło się obok siebie 0, 1 (domyślnie) element
justify-content Ustawia sposób układania elementów obok siebie, gdy ich wymiary nie wypełniają całej szerokości kontenera flex-start, flex-end, center, space-between, space-around, space-evenly kontener

Użycie flexbox do pokazania galerii

Flexbox nadaje się nie tylko do stworzenia layoutu strony. Czasem mamy do pokazania długą listę elementów o tych samych wymiarach (np. miniatury obrazków w galerii) i chcielibyśmy, aby ich ilość w wierszu była zależna od szerokości ekranu.

Spróbujemy rozszerzyć nasz wcześniejszy przykład o taką właśnie listę elementów i tak ustawić CSS, aby dobrze się pokazywały zarówno na smartfonie (mała szerokość ekranu) jak i na dużym ekranie komputera. Zatem rozszerzamy nasz HTML do takiego

<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Przykładowa galeria</title>
</head>
<body>
<header>Nagłówek</header>
<article>
<ul class="flexlist">
<li><div>Element 1</div></li>
<li><div>Element 2</div></li>
<li><div>Element 3</div></li>
<li><div>Element 4</div></li>
<li><div>Element 5</div></li>
<li><div>Element 6</div></li>
<li><div>Element 7</div></li>
<li><div>Element 8</div></li>
<li><div>Element 9</div></li>
<li><div>Element 10</div></li>
</ul>
</article>
<aside>Panel boczny</aside>
<nav>Nawigacja</nav>
<footer>Stopka</footer>
</body>
</html>

W wersji gdzie mamy elementy galerii, w liście zamiast taga <div> będziemy mieć oczywiście <img>.

Teraz podstawowe style dla powyższej listy, aby elementy wyświetlały się jeden pod drugim, na całej szerokości ekranu – czyli wersja na smartfony.

.flexlist {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
margin: 0;
padding: 0;
}
ul.flexlist {
list-style-type: none;
}
.flexlist > * {
flex-basis: 100%;
margin: 1ex;
min-width: 160px;
}
.flexlist > *:nth-child(3n) div {
background: #aaa;
}
.flexlist > *:nth-child(3n+1) div {
background: #ccc;
}
.flexlist > *:nth-child(3n+2) div {
background: #eee;
}

Oprócz używanych wcześniej elementów doszedł tutaj justify-content: space-between. Powoduje on, że wolna przestrzeń pomiędzy elementami w jednym wierszu będzie wypełniona po równo. Nasza strona obecnie wygląda (na smartfonie) w taki sposób

Flexbox z galerią dla smartfonów

Musimy dodać style dla wyższych rozdzielczości. Przyjmijmy, że od 768px szerokości będziemy wyświetlać elementy obok siebie, dając im minimalnie 160px i maksymalnie 240px. W tym celu dodajemy ponownie style w sekcji @media only screen and (min-width:768px):

.flexlist > * {
flex-basis: 200px;
}

Teraz przy szerokości ekranu około 900px nasza strona będzie mieściła 2 elementy obok siebie

Flexbox z galerią dla tabletu

Ale jak będziemy dysponować ekranem szerszym (np. 1024px), to zmieszczą się już 3 elementy obok siebie

Flexbox z galerią dla desktopu

Co najważniejsze, elementy będą „wyjustowane”, tzn. będą miały równe odstępy między sobą, oraz prawy i lewy margines również będą równej wielkości.

Kilka słów na koniec

Jak więc widać, flexbox daje duże możliwości określania layoutu, łącznie ze zmianą kolejności elementów, czy poprawnego skalowania do różnych rozdzielczości ekranu. Dzięki niemu strona stworzona przy użyciu flexbox będzie wyglądała poprawnie zarówno na smartfonie, tablecie jak i komputerze z dużym ekranem.

Jak chcesz przetestować swoją przeglądarkę, zobacz powyższy przykład flexbox.

Chociaż teoretycznie flexbox jest wspierany przez wszystkie popularne przeglądarki (IE11 nie jest już popularne), warto przetestować czy strona faktycznie wszędzie wyświetla się poprawnie.

Jeśli chcecie poczytać dokładniej (strony w języku angielskim) o flexbox, polecam strony do których sięgam w razie potrzeby (również pisząc ten krótki poradnik), czyli CSS-Tricks oraz caniuse.com.