W tej lekcji postaram się zaprezentować pewien sposób myślenia o flexboksie, który może nam pomóc zrozumieć jak on działa. Zaczynajmy.
Ok, pierwsza rzecz – właściwości flex dziecka:
- flex-basis
- flex-grow
- flex-shrink
Wiele osób (uprzedzam, ŹLE) przedstawia, że to pierwsze to jest width, zaś drugie to takie jakby ratio (jednostka fr z grid) a to trzecie to takie media query nieomal, też swego rodzaju ratio.
No, to tak nie wygląda. Już aby lepiej to zrozumieć, to trzeba wybić sobie z głowy te wszystkie ratio i skupić się na prostych wartościach 0 i 1 oraz na flex-basis.
Więc tak – domyślnie flex-grow jest 0 zaś flex-shrink 1. Flex basis to initial size na osi głównej, czyli witdh dla row, height dla column. Jeżeli damy jakąś jednostkę pod flex basis to taki jest initial size, jaki dostanie flex dziecko.
Potem jest patrzenie, czy jest positive space albo negative space. Jeżeli jest positive space to rośniemy, jeżeli mamy włączone grow. Jeżeli jest negative space i mamy włączony shrink… Cóż, to zależy.
Zależy przede wszystkim od rodzica. Bo jeżeli walniemy sobie wszystkim dzieciom np. flex-basis 100% (czy tam 1800px) zaś rodzicowi damy flex wrap wrap, to on, widząc, że nie może obok siebie ustawić tych elementów z zachowaniem flex basis, po prostu je owrapuje, nie patrząc na shrink.
Dopiero, gdy rodzic nie ma flex wrap, ma nowrap, a dzieci na osi głównej nie są w stanie obok siebie wystać z zachowaniem swojego flex basis, dopiero wtedy zachodzi pytanie – shrink czy nie shrink? I jak shrink to się zbijają, tracą szerokość (direction row). Jak nie – wylatują poza stronę, jest overflow.
I to trzeba też zrozumieć – flex basis, flex grow i flex shrink pracują na osi głównej. Tylko oś główna je interesuje. Flex basis to initial width dla direction row oraz initial height dla direction column.
Flex grow oznacza, że element (przy direction row) będzie się rozszerzał czy nie przy positive space. Flex shrink oznacza, czy element (przy direction row) będzie tracił width przy negative space (ale flex wrap rodzica też ma coś do powiedzenia, to już ustaliliśmy).
Ok, dopiero jak to wbijemy do głowy to możemy zawracać sobie łeb jakimiś proporcjami. A teraz jak zrozumieć, która oś jest która?
Cóż, oś główna to ta, na której układamy content. Itemy układamy od lewej do prawej przy row oraz od góry do dołu przy column. I to jest oś główna. Cross axis to ta druga, prostopadła.
Ok, jak zapamiętać justify content? Po pierwsze, justowanie. Jak justowanie tekstu. Po drugie – content. Tak jak content układamy, czyli na osi głównej.
Ok, dlaczego justify content ma space-between | space-around | space-evenly? Cóż, to jest justowanie elementów. Można do prawej, do lewej, do środka, można też je odpychać od siebie. Tylko na osi głównej to można robić.
Na osi cross nie można tego robić, bo tam nie ma żadnych elementów. Względnie, jest tam wrapowany content (drugi wiersz lub kolumna) i align content też może justować te rzędy/kolumny.
Ok, dlaczego align items? Align czyli doklej do jakiegoś kierunku. Items, czyli przedmioty, nie żaden content, nie pracujemy contentem, nie justujemy, po prostu na osi cross doklejamy do którejś ze stron: flex-start | flex-end | center | baseline | stretch
Czyli start i end oraz center można zrozumieć łatwo, na tej osi przeciwnej do osi kontentu albo początek, środek albo koniec. A baseline i stretch?
Cóż, strech, domyślny zresztą, to rozlej się na całość. Czyli jak mamy direction row, to nasza oś cross to jest góra dół czyli align items stretch to jest rozlej się na całą (wysokość). Kierunek przeciwny do flex basis.
Baseline, cóż, są obrazki w internecie, które to tłumaczą. I raz jeszcze – nie ma tam żadnego justowania, bo to oś przeciwna do tej, na której kontent ustawiamy. To tak, jakby ktoś chciał w Wordzie justować napisy do góry albo do dołu. Nie może.
Może sobie ustawić, czy chce tak lub inaczej wyjustowany tekst dokleić na początek strony, koniec albo środek. Nie ma justowania w kierunku prostopadłym do tego, na który wrzucamy kontent. W wordzie jest jeden taki możliwy kierunek, od lewej do prawej, w flexbox mamy aż 4, ale powoli zaczynamy łapać.
Ok, a align content? Jak mamy więcej rzędów lub kolumn to zarządzamy w ten sposób contentem: flex-start | flex-end | center | space-between | space-around | stretch.
Tak, contentem. Z naciskiem na content. Możemy tego nie wiedzieć, ale flexbox używać box sizing content box. Bo musi, inaczej jakby shrinkowało elementy razem z borderem to by jakaś masakra była.
Z drugiej strony – align, nie justify. Nie justujemy, ale poniekąd justujemy rzędy/kolumny, w kierunku prostopadłym do osi głównej. Tutaj stretch to będzie rozlanie się tych rzędów w wysokości (lub kolumn w szerokości) aby się stykały ze sobą.
Reszta, cóż, działa podobnie, pobaw się człowieku, zobaczysz. Ważne, abyś zapamiętał i jako tako zrozumiał, aby nie myliło ci się co jest co.
Teraz align self. To jest ustawianie jednego dziecka na osi cross (przeciwnej do głównej) inaczej niż reszta dzieci, co ma jego rodzic ustawione. Dlaczego nie ma justify self? Bo nie można tak.
To tak, jakby ktoś chciał wyjustować tekst w Wordzie, a potem zastosować zupełnie inne justowanie dla jednej litery. To tak nie działa.
Ok, to chciałbym jeszcze na jedną rzecz zwrócić uwagę. W sumie dwie. Jedna jest taka, że wewnątrz flex kontenera margin auto pozwala na centrowanie i w pionie i w poziomie (jakby już bez tego flexbox nie był wystarczająco zagmatwany).
Druga rzecz, wyobraź sobie, że masz flex direction column. Tak? I flex basis to initial height, tak? I flex grow 1 oznacza, że jak jest miejsce, to zdobywa wysokość, tak?
Ok, a jak zatem sprawić, aby „rosło” jeżeli chodzi o width? Ale nie powyżej jakiejś tam liczby?
Cóż, trzeba dać width 100% i max width np. 800px. I to jest jeden z tych przypadków, gdzie width i max width używamy ze sobą i to się nie wyklucza, tylko komplementuje.
Bo jak nie ma 100%, to zostanie przy takim width jaki potrzebuje kontent (flex grow tutaj nie działa, bo column). Z drugiej strony, jak jest 100%, to się rozlewa na całą szerokość. I wtedy max-width z wartością absolutną nas ratuje.