O Flexboxie

Flexbox to obecnie jedno z coraz bardziej powszechnych narzędzi w arsenale front-end developerów. Jego pojawienie się w 2017 roku znacznie uprościło rozmieszczanie i wyrównywanie elementów strony w pożądany sposób. Koncept elastycznych kontenerów usprawnia nadawanie stylów odpowiedzialnych za położenie elementów HTML wyświetlanych na różnych rodzajach urządzeń i rozmiarach ekranów. Poniżej zamieszczam subiektywne zestawienie najczęściej używanych właściwości we Flexbox wraz z podglądem efektów w przeglądarce Chrome.

Spis treści

Deklarowanie użycia Flexboxa w kontenerze

Żeby korzystać z dobrodziejstw Flexboxa należy zadeklarować jego użycie w wybranym elemencie-rodzicu, czyli kontenerze. W tym celu należy zmienić jego właściwość display na flex lub inline-flex (dla elementów liniowych). Poniższe przykłady obrazują różnice wynikające z użycia dyrektywy display: flex oraz jej braku:

<style>
  .my-box {
    display: flex;
    width: 600px;
    height: 200px;
    background-color: red;
  }
  .mini-box {
    width: 100px;
    height: 100px;
    background-color: green;
    border: 1px solid black;
    margin: 50px;
  }
</style> 
(...)
<div class="my-box">
  <div class="mini-box"></div>
  <div class="mini-box"></div>
  <div class="mini-box"></div>
</div>

Dla porównania ten sam kod z inicjalną wartością właściwości display dla elementu <div>, czyli block:

<style>
  .my-box {
    display: block;
    width: 600px;
    height: 200px;
    background-color: red;
  }
  .mini-box {
    width: 100px;
    height: 100px;
    background-color: green;
    border: 1px solid black;
    margin: 50px;
  }
</style> 
(...)
<div class="my-box">
  <div class="mini-box"></div>
  <div class="mini-box"></div>
  <div class="mini-box"></div>
</div>

Osie we Flexboxie

Deklarowanie układu elementów odbywa się przy użyciu dwóch osi. Do tego celu należy ustawić wartość właściwości flex-direction. Możliwe do wyboru opcje to row, column, row-reverse, column-reverse, initial, inherit oraz unset. Tym sposobem nadajemy wartość osi głównej (main axis). Druga oś będzie prostopadłą do osi głównej – oś prostopadła (cross axis).

Pytanie-zagadka: w poprzednim akapicie zademonstrowałam działanie dyrektywy display: flex, jednak bez podawania wartości właściwości flex-direction, a pomimo tego zielonej kwadraty zostały ułożone w poziomym rzędzie. Dlaczego tak się stało? Ponieważ wartość row to wartość domyślna właściwości flex-direction, zatem nie trzeba ustawiać jej wprost.

Porównanie elementów w przypadku zastosowania wartości row oraz row-reverse dla właściwości flex-direction obrazują poniższe przykłady:

<style>
  .my-box {
    display: flex;
    flex-direction: row;
    (...)
  }
</style> 
(...)
<div class="my-box">
  <div class="mini-box">1</div>
  <div class="mini-box">2</div>
  <div class="mini-box">3</div>
  <div class="mini-box">4</div>
  <div class="mini-box">5</div>  
</div>

Dla row-reverse efekt będzie następujący:

<style>
  .my-box {
    display: flex;
    flex-direction: row-reverse;
    (...)
  }
</style> 
(...)
<div class="my-box">
  <div class="mini-box">1</div>
  <div class="mini-box">2</div>
  <div class="mini-box">3</div>
  <div class="mini-box">4</div>
  <div class="mini-box">5</div>
</div>

Przy użyciu wartości row-reverse elementy nie tylko zostały ułożone w odwrotnej kolejności, ale również zostały wyrównane do przeciwległego boku kontenera, czyli od prawej do lewej. Oczywiście dla wartości column i column-reverse sytuacja będzie wyglądała analogicznie, z tym że elementy zostaną ustawione w pionie jeden pod drugim od góry do dołu, lub od dołu do góry (reverse).

Ustawienie elementów głównej osi

Ustawianie elementów w osi głównej nie ogranicza się bynajmniej do wyboru kierunku osi oraz ewentualnego skorzystania z opcji reverse. Jedną z możliwości ustawiania elementów jest nadanie wartości dla właściwości justify-content, oczywiście dla elementu-rodzica. Właściwości jakie oferuje Flexbox to między innymi flex-start, flex-end, center, space-between, space-around oraz space-evenly. Poniżej prezentuję zachowanie elementów dla poszczególnych wartości właściwości justify-content przy zastosowaniu dyrektywy flex-direction: row.

  • flex-start
  • flex-end
  • center
  • space-between
  • space-around
  • space-evenly

Warto pochylić się nad trzema ostatnimi wartościami: space-between ustawia elementy w równych odstępach „przyklejając” pierwszy element do początku kontenera (tam, gdzie w zależności od ustawień znalazłby się flex-start), a ostatni „przykleja” do jego końca. W odróżnieniu space-around otacza każdy element z obu stron tę samą ilością miejsca, co oznacza że element nr 1 ma po swojej lewej jedną jednostkę przestrzeni, ale z prawej oddzielają go od elementu nr 2 dwie jednostki przestrzeni. Natomiast space-evenly otacza każdy element z obu stron tę samą ilością miejsca, czyli element nr 1 oraz każdy kolejny mają po obu stronach tyle samo miejsca.

Dla porównania poniżej znajdują się te same wartości właściwości justify-content zastosowane z dyrektywą flex-direction: row-reverse.

  • flex-start
  • flex-end
  • center
  • space-between
  • space-around
  • space-evenly

Zawijanie elementów

Można sobie wyobrazić sytuację kiedy szerokość wszystkich elementów razem wziętych jest większa niż szerokość kontenera, albo kiedy tej szerokości po prostu nie znamy. Do obsługi takich sytuacji idealnie nadaje się właściwość flex-wrap. Przyjmuje trzy wartości: no-wrap, wrap oraz wrap-reverse. Wartość no-wrap jest ustawiana domyślnie i może spowodować nieoczekiwane efety.

W poniższym przykładzie każdy z elementów potomnych ma zadeklarowaną wysokość i szerokość na 50px, jednak zostały skurczone, ponieważ nie mieściły się w elemencie-rodzicu. Ponadto ostatni element jest o 10px szerszy od pozostałych.

<style>
  .my-box {
    display: flex;
    flex-direction: row;
    justify-content: flex-start;
    (...)
  }
  .mini-box {
    width: 50px;
    height: 50px;
    (...)
  } 
</style>
(...)
<div class="my-box">
  <div class="mini-box">1</div>
  <div class="mini-box">2</div>
  (...)
  <div class="mini-box">10</div>
</div>

Zmiana wartości właściwości flex-wrap na wrap pozwoli uzyskać poniższy efekt:

Tło jest efektem sztywnego ustawienia rozmiarów kontenera.

Ustawienie elementów osi prostopadłej

Elementy wewnątrz kontenera można układać również w płaszczyźnie prostopadłej do osi głównej. Służy do tego właściwość align-items i może ona przyjmować między innymi takie wartości: flex-start, flex-end, center oraz baseline. Właściwość tę nadaje się elementowi-rodzicowi.

Poniżej prezentuję efekt użycia każdej z wymienionych wartości dla kontenera z zastosowanymi dyrektywami flex-direction: row oraz justify-content: flex-start.

  • flex-start
  • flex-end
  • center
  • baseline

Ustawianie pojedynczego elementu

Omówione przeze mnie do tej pory dyrektywy były stosowane na elemencie-rodzicu, jednak nie dotyczy to wszystkich właściwości oferowanych przez Flexbox. Jedną z nich jest align-self, która służy do ustawiania wybranego elementu na osi prostopadłej. Może przyjmować między innymi takie wartości jak flex-start, flex-end oraz center. Wartość auto jest wartością domyślną i oznacza dostosowanie elementu do wartości nadanej osi prostopadłej.

Poniżej znajdują się przykłady zastosowania wartości dla właściwości align-self pierwszego elementu w kontenerze, w którym zastosowano dyrektywy flex-direction: row, justify-content: flex-start oraz align-items: flex-start.

  • flex-start
  • flex-end
  • center

Podsumowanie

Flebox jest niesamowicie użytecznym narzędziem, który służy front-end developerom do rozmieszczania elementów wewnątrz kontenerów. Warto zwrócić jednak uwagę, że jest przeznaczony dla elementów lub layoutów w mniejszej skali. Jeżeli natomiast naszym zadaniem jest ułożenie layoutu złożonego z wielu zależnych od siebie w położeniu elementów, to lepiej do tego zadania sprawdzi się np. Grid.

Trzeba również mieć świadomość, że chociaż wsparcie dla Flexboxa jest dzisiaj (tj. 2 lutego 2020 r.) bardzo dobre, to jednak nie wszędzie będzie można z niego skorzystać. Dość powszechne są problemy z zachowaniem elastycznego wyświetlania elementów w przeglądarce Internet Explorer 11 (o wcześniejszych nie wspominając) oraz np, w CMS typu WordPress. Poniżej zamieszczam zrzut ze strony caniuse.com, na której można sprawdzić aktualne wsparcie (dla oszczędności miejsca legendę przeniosłam wyżej).

Jedna odpowiedź

  1. Guma pisze:

    Bardzo fajny poradnik!

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *