W nowoczesnych stronach internetowych, jednym z najważniejszych elementów jest sam layout strony. Układ elementów w konkretnych miejscach, zależnych względem innych lub niezależnych od siebie. Stosujemy do tego różnego rodzaju rozwiązania, korzystając najczęściej z gotowych bibliotek, zawierających w sobie gotowe układy, wykorzystujące różne techniki. Na początku web designu, strony były tylko zwykłymi dokumentami zawierającymi treści, z czasem dochodziły do tego nowe elementy jak obrazki, szeroko rozumiana stylizacja treści, jak kolory i rozmiary fontów, kolory tła itd. Jednym z pierwszych rozwiązań odpowiadających za układanie elementów w ściśle określonych pozycjach, a nie jeden pod drugim były tabele, które poniekąd, ze swoją ubogą strukturą, nadal są stosowane w szablonach e-mailingowych. Wraz z wejściem kaskadowych arkuszy styli, pojawiło się sporo możliwości.
W dzisiejszym artykule zajmiemy się Flexem, ostatnimi czasy najczęściej wykorzystywaną metodą odpowiadającą za układ na stronie internetowej. Równie często nie do końca zrozumiałej w działaniu i niewykorzystywanej w pełni jej potencjału.
Czym jest Flex?
Zasadniczo, flex jest zaawansowaną, a zarazem prostą strukturą tabelaryczną, posiadającą wszystko, co było najlepsze w tabelach, bez ich ograniczeń, z dodatkowymi udogodnieniami i usprawnieniami. Dodatkowe opcje umożliwiają nam pełną kontrolę nad dowolnymi grupami elementów, jak i pojedynczymi przypadkami.
Flex składa się z 2 podstawowych składników: rodzica oraz dzieci.
W rodzicu definiujemy podstawowe informacje, czyli informujemy element, że ma być flexem, ustalamy, jak ma układać wewnątrz siebie dzieci, ich kierunek, wyrównanie lewo, prawo, góra, dół, środek wertykalny, środek horyzontalny, oraz czy te elementy mogą wychodzić poza obszar rodzica, czy nie.
Podobnie jak w tabelach mamy i rzędy i kolumny, ale w przeciwieństwie do tabel mamy tu zapewnioną pełną elastyczność (flexibility). Ta elastyczność zapewnia nam możliwość zmiany orientacji kierunku układania elementów, zmiany rozmiarów, rozciąganie, zwężanie itd.
Często przy prostych układach, zwykłe elementy blokowe czy inlinowe wystarczają, ale w bardziej skomplikowanych sytuacjach to jest właśnie jedno z rozwiązań, które zapewni nam wszystko, czego prawdopodobnie potrzebujemy.
Flex w praktyce.
Zaczynając od podstaw, aby skorzystać z Flex, musimy mieć co najmniej 2 elementy rodzica i dziecko/dzieci.
<div class="flex">
<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>
.flex {
display: flex;
…
}
.item {
…
}
Mając tak uproszczoną strukturę oraz praktycznie jedną linijkę kodu, mamy już dostęp do pełni funkcjonalnego Flex’a. Tylko z tym małym fragmentem kodu, nasze elementy już są układane przez magię Flex’a. Bez dodatkowych parametrów, Flex traktuje nasze elementy automatycznie do ich zawartości. Układa je default’owo od lewej do prawej, bez łamania rzędu, co oznacza, że jeśli będzie ich więcej niż może się zmieścić, Flex będzie próbował ścieśnić je na szerokość, aby było ich jak najwięcej widać. Jeśli i tak nie będą się mieścić, wyjdą poza obszar rodzica.
Ponadto, wszystkie będą miały tę samą wysokość względem najwyższego z nich.
Możemy wpłynąć na oba te zachowania, dodając parę parametrów, po pierwsze łamać rzędy, jeśli elementy się w nich nie mieszczą, ustawiając parametr {flex-wrap: wrap;}
, po drugie, zmieniając przykładowo parametr {align-item: center;}
.
Dzięki tym parametrom informujemy rodzica, aby łamał rząd, i niemieszczące się dzieci układał w kolejnych. Dodatkowo wycentrował ich pozycję horyzontalną względem najwyższego z nich w danym rzędzie i ustawiał im automatyczną wysokość względem zawartości.
Podstawową własnością jest też kierunek układania dzieci. Domyślnie jest to układanie w rzędzie {flex-direction: row;}
ale możemy też ustawić układ kolumnowy dyrektywą {flex-direction: column;}
.
Przypomina on trochę układ blokowy tyle, że jeśli ustawimy jakąś konkretną wysokość rodzica, to dzieci przejdą obok do drugiej kolumny lub wyjdą poza obszar. Podobnie jak w przykładach powyżej, tylko w innym kierunku.
Możemy jeszcze wycentrować elementy wertykalnie, do środka lewej lub prawej strony, dyrektywą: {justify-content: center/flex-start/flex-end;}
a wygląda to mniej więcej jak na wizualizacji poniżej.
Jedną z najmocniejszych cech Flex’a, jest możliwość odwracania kolejności elementów. Możemy tego dokonać na parę sposobów. Przykładowo możemy ustawić dyrektywę {flex-wrap: wrap-reverse;}
co ustawi nasze elementy w odwróconej kolejności od dołu do góry, z lewej na prawą.
Innym sposobem dający podobny, acz trochę inny efekt to ustawienie dyrektywy: {flex-direction: row-reverse;}
ustawiającej nasze elementy w kolejności od góry do dołu, ale z prawej do lewej.
Łączące obie reguły, mamy pełne odwrócenie wszystkich elementów, i ustawienie ich od dołu do góry, od prawej do lewej.
Ponad opisane wyżej własności możemy jeszcze wpływać bezpośrednio na wygląd i zachowanie dzieci Flex’owe. Podstawową wartością, którą możemy ustawić, jest zbiorcze {flex:0 0 auto;}
przyjmujące 3 wartości. Można je rozdzielić niezależnie na:
{
flex-grow: 0;
flex-shrink: 0;
flex-basis: auto;
}
Każda z nich odpowiada za rozmiar elementu, a bardziej jak Flex ma je traktować.
Pierwsza nich mówi o tym, czy element ma rosnąć, wypełniając dostępne wolne miejsce, o ile takie jest.
Następna odpowiada za kurczenie się elementu, jeśli jego zawartość na to pozwala. Ostatnia odpowiada za początkowy rozmiar elementu, od którego powyższe modyfikacje mają brać jako bazę.
Wizualizując powyższe, w naszym przykładzie możemy skrótowo napisać dyrektywę {flex: 1 1 25%;}
lub niezależnie każdą z nich oddzielnie uzyskując ten sam efekt.
Możemy również wpływać na pojedyncze elementy nie na całą grupę. W tym wypadku również mamy możliwość zmiany kolejności poszczególnych dzieci, nadając im przykładową własność {order: 10;}
Kolejną dyrektywą wpływającą na pojedynczy element może być {align-self: flex-end;}
która odpowiada za ułożenie danego dziecka względem innych dzieci. W naszym przykładzie domyślnie elementy wymiarami dostosowują się do największego w rzędzie, a dla wizualizacji powyższej własności, element dwunasty dostaje automatyczną wysokość i wyrównuje się do dołu.
Haxy
Są jeszcze własności rzadko opisywane w dokumentacjach, czy innych artykułach. Potocznie nazywamy je haxami. Jednym z nich jest prosta dyrektywa {margin: auto;}
, zależnie od aktualnej sytuacji, dzięki której jeden z elementów może wpłynąć na swoje położenie względem innych. Wizualizując na naszym uproszczonym przykładzie, możemy odsunąć przykładowy element trzynasty od innych, ustawiając mu {margin-left: auto;}
.
Podobny przypadek, również wykorzystujący hax z marginesem, to ustawienie elementu wertykalnie. Przykładowo, jeśli dzieci nie będą rozciągane względem największego i wszystkie będą wyrównane do dołu, możemy jeden z nich (8) ustawić {margin-bottom: auto;}
co wyrówna go do góry, lub możemy ustawić (9) margines automatyczny góra/dół co wyrówna go w pionie. Peny margines automatyczny dla pojedynczego elementu (12), {margin: auto;}
wyrówna go w każdym z kierunków, rozpychając inne elementy na boki.
Podsumowując:
Więcej na temat podstawowych własności elementów Flex’owych możemy poczytać w oficjalnej dokumentacji lub np. tu (css-tricks). Niestety nie wszystko da się przenieść bezpośrednio na dany problem, z jakim możemy się spotkać podczas projektowania layout Flexem. Czasem drobne różnice w interpretacji arkusza styli w różnych przeglądarkach, powodują ciut inne zachowanie, niż to jakie byśmy chcieli i trzeba na to zwracać uwagę. Zwłaszcza jeśli część kodu pominiemy, mając nadzieję na domyślne zachowanie, które może się mocno różnić.
Tu przydaje się nasze doświadczenie i wiedza w zrozumieniu działania konkretnych ustawień w celu uzyskania zamierzonego efektu na różnych urządzeniach i przeglądarkach. Chętnie pomożemy rozwiązać wasze problemy, zapraszamy do kontaktu i do następnego bloga.