Zrozumieć Flexboxa
Cześć! Mam na imię Wojtek, cieszę sie, że trafiłeś na mój kurs CSS Flexbox.
W tej lekcji dowiesz się czym jest CSS Flexbox oraz jak przy jego pomocy tworzyć layouty. Omówię zasady, według których flex pozycjonuje elementy na stronie, najważniejsze właściwości oraz przydatne skróty, które zaoszczędzą Ci pisania wielu linijek. kodu Pod koniec kursu stworzymy pełny layout, wykorzystując do tego właśnie flexa.
Zanim jednak do tego dojdziemy - zobaczmy jak prezentuje się wsparcie przeglądarek dla flexboxa:
Jak widzisz, wsparcie na dzień dzisiejszy jest na tyle dobre, że zaryzykuję stwierdzenie, że możesz użyć flexboxa bez większych obaw.
Oczywiście, jeśli przeglądarka, którą musisz wspierać w swoich projektach, nie widnieje na liście bądź po prostu wiesz, że nie wspiera flexboxa - wtedy pozostają inne metody pozycjonowania lub tzw. polyfille.
Zanim jednak przejdziemy do nauki flexboxa, stworzymy kartę, która będzie jednym z elementów jakimi flexbox będzie zarządzał. Potraktuj to jako prostą rozgrzewkę - zależy mi na tym, abyś rozumiał każdy fragment kodu, który będziemy omawiali.
Rozgrzewka
Stwórzmy więc markup, na którym będziemy pracowali - w pliku index.html stworzymy sekcję o klasie .card-section, czyli główny kontener na wszystkie nasze karty.
Każda z kart będzie po prostu znacznikiem div o klasie card - w tym momencie nie znamy określonej funkcji naszej karty, dlatego może to być neutralny semantycznie div.
Wewnątrz niego umieścimy plakietkę, w której znajdzie się numer karty oraz akapit z jej treścią.
Następnie stworzymy plik styles.css oraz załadujemy go do naszej strony przy pomocą znacznika link.
Nadajmy .card-section tło o kolorze #f7f8f8, a następnie ustalmy wymiary karty na 130px wysokości i 100px szerokości. Zaokrąglimy jej rogi oraz nadamy cień i margines.
Ustalmy kolor, rozmiar i justowanie tekstu - oraz dodatkowo zresetujmy domyślne marginesy wewnętrzne i zewnętrzne na body.
Na ten moment wygodniej byłoby nam, gdyby nasza sekcja zajmowała 100% szerokości i wysokości dostępnej przestrzeni, więc to pierwszy krok aby to osiągnąć.
Naszej plakietce nadamy wysokość 70px oraz 100% szerokości rodzica, czyli w tym przypadku 100px. Rozmiar czcionki ustawimy na 36px, natomiast by wycentrować tekst w pionie ustawimy line-height równy wysokości kontenera - czyli 70px.
Ustawimy też naszej sekcji .card-section szerokość i wysokość równą 100%, padding: 5px oraz box-sizing ustawione na border-box by zajmowała ona całą dostępną przestrzeń.
Pozostało ustawić kolor tła i tekstu - i nasza pojedyncza karta jest już niemal gotowa. Na .card ustawimy overflow:hidden - tak, by jego zaokrąglone obramowanie przycięło nam plakietkę i cała karta dalej miała zaokrąglone boki w każdym rogu.
Dla lepszego efektu pobierzemy czcionkę Montserrat z Google Fonts i wykorzystamy ją jako główny font dla naszego body poprzez właściwość font-family.
Analogicznie stworzymy jeszcze 5 kart, z czego każda kolejna będzie miała wyższy numer oraz inny kolor tła. Aktualizujemy teraz markup w pliku index.html oraz dodajemy selektory ustawiające kolory tła dla kolejnych kart - wykorzystamy do tego klasy card-x gdzie x będzie odpowiadał numerowi karty. Dzięki temu w prosty sposób powiążemy kod widoczny w edytorze z rezultatem widocznym w podglądzie.
Jeśli wiesz jak, możesz wykorzystać do tego CSS Counters - ja pozostanę przy opcji ręcznego wpisania numeru do kodu HTML.
Jak widzisz, wszystkie nasze karty są już gotowe. Cała szóstka ułożyła się blokowo - jedna pod drugą. Nadeszła więc pora na zabawę flexboxem!
Do roboty
Oto sedno tego kursu - CSS Flexbox. Pierwszą bardzo ważną cechą tej metody tworzenia layoutów są zależności rodzic-dziecko. To kontener nadrzędny definiuje jak elementy wewnątrz niego będą się zachowywały - kontrolując ich wymiary oraz pozycje.
To często wygodniejsze podejście niż tworzenie skomplikowanych, zagnieżdżonych selektorów które musielibyśmy stworzyć bez flexa.
Flexa „włączamy” za pomocą display: flex. Element, który ma na sobie taką własność zaczyna pozycjonować swoje bezpośrednie dzieci według specyfikacji. Nadajmy więc „flexa” na sekcji .card-section.
Jak widzisz, wszystkie karty są teraz obok siebie. To wynika jednej z właściwości powiązanych z flexboxem: flex-drection. Przyjmuje ona jedną z czterech wartości: row, row-reverse, column oraz column-reverse.
Dodatkowo, jeśli nasz kontener jest zbyt wąski to karty kurczą się odpowiednio, tak by każda z nich miała tę samą szerokość oraz by wszystkie były widoczne. Za to odpowiada właściwość flex-shrink, ale o niej opowiem Ci później. Po kolei:
Wartością domyślną dla flex-direction jest row - jej efekt widzisz w podglądzie. Ustawia ona elementy wewnątrz kontenera w wierszu, jeden obok drugiego, w kolejności od lewej do prawej. Widzimy teraz efekt końcowy - ale jak to tak naprawdę działa?
W przypadku flexboxa musimy rozróżnić dwie osie, względem których pozycjonowane są elementy: main-axis oraz cross-axis - czyli po prostu główną oś oraz przeciwstawną. Ustawiając flex-direction definiujemy, która z osi jest osią podstawową. Za oś poziomą odpowiada row, natomiast za oś pionową - column.
Za chwilę ustawimy flex-direction: column na naszym .card-section. Zanim jednak to nastąpi - najedź kursorem myszy na podgląd po prawej stronie ekranu. Zobaczysz wizualizacje osi, na których bazuje flex-box - jak widzisz, przy domyślnej wartości row naszą główną osią jest pozioma oś X.
Zmieńmy więc domyślną wartość flex-direction na column.
Jak widzisz w podglądzie, elementy są teraz ułożone jeden pod drugim - podobnie jak w sytuacji, kiedy w ogóle nie stylowaliśmy naszych kart na flexie.
Mimo wszystko na pierwszy rzut oka widać już różnicę - w przypadku rozwiązania opartego na flexie, wszystkie nasze elementy skurczyły się tak, by mieścić się w naszym kontenerze. Ponownie dzieje się to za sprawą flex-shrink, o którym opowiem Ci w drugim rozdziale. Póki co, zobacz jak ustawienie kierunku flexa na kierunek kolumnowy wpłynęło na osie w naszym kontenerze, najeżdżając kursorem na podgląd.
Teraz to oś pionowa jest naszym main-axis. Natomiast oś przeciwstawna, cross-axis jest teraz osią poziomą. Ich role zostały odwrócone. Wszystkie karty układają się teraz od góry do dołu, ponieważ to oś pionowa jest tą podstawową.
Znamy więc sposób na zamianę naszej głównej osi wzdłuż której układa się nasz layout. Jednak to nie wszystko, za co odpowiedzialne jest flex-direction - musimy jeszcze omówić właściwości row-reverse oraz column-reverse.
Testujemy więc column-reverse. Przyrostki -reverse na wartościach flex-direction definiują kierunek naszych osi. Zobacz, że wszystkie elementy są teraz numerowane od dołu do góry - czyli karta, która pierwotnie znajdowała się najdalej w kodzie HTML, teraz wyświetla się pierwsza. W wizualizacji osi flexboxa zobaczysz, że tym razem strzałka symbolizująca kierunek osi pionowej będzie skierowana w górę - właśnie za sprawą -reverse.
To znaczy, że pierwsza część wartości flex-direction definiuje nam, która oś będzie naszą osią podstawową, natomiast przyrostek -reverse odwraca jej kierunek. Sprawdźmy, czy zadziała to dla wartości row-reverse.
Zgadza się! Czyli potrafimy kontrolować kierunek naszej osi podstawowej oraz decydować, względem której nasze elementy będą się układały - to już bardzo dużo. Jak kontrolować kierunek osi przeciwnych? To już jest niestety mniej oczywiste - musimy wykorzystać właściwość flex-wrap.
Właściwość flex-wrap ustala jak powinny zachowywać się dzieci znacznika o właściwości display: flex; w przypadku kiedy już się w nim nie mieszczą. Jego domyślna wartość to no-wrap - czyli elementy w ogóle nie próbują zawijać się do następnych linii.
Zobaczmy jak to działa, ustawiając właściwość flex-wrap na wartość wrap dla .card-section
Jak widzisz, im węższy ekran - tym więcej linii stworzy flex. Nasze karty mają wkońcu tę zadeklarowaną szerokość 100px, ponieważ mogą układać się w wielu liniach. Układ widoczny obecnie w podglądzie po prawej stronie działa podobnie jak w piśmie arabskim/hebraiskim. O zarządzaniu liniami flexboxa i o tym, jak one dokładnie działają dowiesz się w kolejnych rozdziałach - my natomiast chcieliśmy odpowiedzieć na pytanie - jak odwrócić kierunek osi przeciwstawnej? Analogicznie do sytuacji z flex-direction, musimy użyć przyrostka -reverse.
Wartość wrap-reverse na właściwości flex-wrap nie tylko umożliwi zawijanie elementów do następnego wiersza, ale również odwróci kierunek osi przeciwstawnej, drugorzędnej!
Jak widzisz w podglądzie, cross-axis biegnie teraz w przeciwnym kierunku. To znaczy, że w tym przypadku karty zaczynają rysować się od prawego dolnego rogu, kolejne elementy umieszczane są po lewej oraz zawijają się w górę, w przypadku, gdy nie mieszczą się w jednej linii.
No dobrze, ale tak działa zawijanie linii flexa, gdy osią główną jest oś pozioma. Co w przypadku, gdybyśmy zmienili flex-direction na column oraz uruchomili zawijanie wierszy?
Jak widzisz, karty układają się z góry na dół oraz domyślnie zawijają się w ten sposób, że kolejne linie umieszczane są po prawej stronie. Ilość kolumn zależy oczywiście od wysokości kontenera.
Jeśli wybierzemy wrap-reverse, elementy będą rysowane od prawej strony. To znaczy, że linie z zawiniętymi elementami flexa pojawią się po lewej stronie. Tutaj można się dopatrzeć analogii do tradycyjnego piśma chińskiego i japońskiego. Jeśli analogia piśmiennicza do Ciebie przemawia możesz odwiedzić tą stronę i przeczytać sekcję "Kierunek pisania".
Flex jest bardzo elastyczny - stąd jego nazwa. Możesz też łączyć wartości row-reverse oraz column-reverse z poznanymi przed chwilą wartościami flex-wrap. Zobacz, że to tylko trzy właściwości, a ile możliwych układów!
Pamiętaj też, że wyżej wymienione właściwości działają tylko wtedy, kiedy element ma ustawiony display na flex, jak zresztą wszystkie właściwości powiązane z flexem. Po prostu - jeśli chcemy używać możliwości flexa, musimy ustawić nadrzędnemu kontenerowi display: flex.
Poeksperymentuj z różnymi kombinacjami flex-direction i flex-wrap oraz obserwuj w podglądzie jak zachowują się poznane osie cross-axis i main-axis.
W kolejnym rozdziale dowiesz się, jak układać elementy względem poznanych osi, wykorzystując do tego właściwości justify-content, align-content i align-items.