Oś główna i oś poprzeczna, display flex, justify-content i align-items, siatka z grid-template-columns i grid-template-areas oraz układ panel 30 procent obok bloku głównego 70 procent z arkusza CKE. Lekcja 4.7 kursu INF.03.
Flexbox i grid to dwa mechanizmy CSS do rozkładania bloków na stronie: flexbox układa je w jednym kierunku, w wierszu albo w kolumnie, a grid rozstawia je w siatce z kolumn i wierszy. Oba zastąpiły float (obtekanie) w budowie kolumn, bo do ustawiania bloków obok siebie zostały zaprojektowane, a float służy do oblewania obrazu tekstem. W części pisemnej pytania wprost o flexbox trafiają się rzadko, ale rysunek układu bloków 2 do 5 z czterema wersjami kodu CSS do wyboru wraca regularnie. W zadaniu praktycznym to najkrótsza droga do polecenia „panel lewy o szerokości 30 procent, blok główny 70 procent, oba obok siebie".
Flexbox: kontener i elementy flex
Kontener flex to element, któremu przypisano display: flex; jego bezpośrednie dzieci stają się elementami flex i ustawiają się w jednym wierszu obok siebie, niezależnie od tego, że są blokami. Deklarację stawia się zawsze na RODZICU, a nie na dzieciach: dzieci nie dostają żadnej własnej właściwości, tylko nowy sposób rozstawienia. Elementem flex zostaje wyłącznie dziecko bezpośrednie, więc bloki schowane o poziom głębiej układ pomija.
Kontener ma dwie osie i od nich zależy działanie wszystkich pozostałych właściwości. Oś główna (main axis) biegnie w kierunku, w którym idą elementy: przy domyślnym flex-direction: row poziomo, od lewej do prawej. Oś poprzeczna (cross axis) jest do niej prostopadła, więc przy wierszu biegnie w pionie. Po zmianie kierunku na flex-direction: column osie zamieniają się rolami: główna staje się pionowa, a poprzeczna pozioma.
Kontener flex z trzema elementami: oś główna biegnie poziomo i rozkłada elementy właściwością justify-content, oś poprzeczna pionowo i wyrównuje je przez align-items
Rysunek pokazuje jedyną rzecz, którą trzeba tu zapamiętać: justify-content rozkłada elementy wzdłuż osi GŁÓWNEJ, a align-items wyrównuje je wzdłuż POPRZECZNEJ.
Właściwość kontenera
Co ustawia
Wartości
display
włącza układ elastyczny
flex
flex-direction
kierunek osi głównej
row, column
flex-wrap
zawijanie do kolejnej linii, gdy brak miejsca
nowrap, wrap
justify-content
rozmieszczenie wzdłuż osi głównej
flex-start, center, space-between, space-around
align-items
wyrównanie wzdłuż osi poprzecznej
stretch, center, flex-start
gap
odstęp między elementami
10px, 20px
Wartości justify-content różnią się tym, gdzie ląduje wolne miejsce. flex-start upycha elementy na początku wiersza, center pośrodku, space-between rozsuwa je na całą szerokość tak, że pierwszy dotyka lewej krawędzi, a ostatni prawej, space-around zostawia odstęp także przy krawędziach. Przerwy między elementami wygodniej ustawić właściwością gap niż marginesami zewnętrznymi, bo gap nie dokłada niczego przed pierwszym i za ostatnim blokiem.
Właściwość elementu
Co robi
flex: 1
element rośnie i dzieli wolne miejsce po równo z innymi
flex: 0 0 30%
element ma dokładnie 30 procent, nie rośnie i się nie kurczy
flex-basis
rozmiar wyjściowy, od którego zaczyna się podział miejsca
order
kolejność wyświetlania, niezależna od kolejności w kodzie HTML
align-self
wyrównanie w poprzek tego jednego elementu, wbrew align-items
Menu poziome to najczęstsze zastosowanie flexboksa w naszym sklepie komputerowym. Menu jest w HTML listą punktowaną zamkniętą w <nav>, więc punkty stoją jeden pod drugim; display: flex na liście ustawia je w rzędzie, a list-style-type: none usuwa punktory.
nav ul {
display: flex;
gap: 20px;
list-style-type: none;
padding: 0;
}
Drugie zastosowanie to wyśrodkowanie zawartości w pionie i w poziomie naraz, czego marginesami zrobić się nie da. Baner sklepu ma w arkuszu podaną wysokość, a napis ma stać w jego środku.
header {
display: flex;
justify-content: center;
align-items: center;
height: 80px;
background-color: DarkSlateGray;
}
Grid: kolumny, wiersze i linie siatki
Grid to układ dwuwymiarowy: display: grid na rodzicu dzieli go na kolumny i wiersze, a dzieci wpadają w kolejne komórki tej siatki. Liczbę i szerokość kolumn podaje grid-template-columns, a wysokość wierszy grid-template-rows. Zapis 30% 70% daje dwie kolumny o takich właśnie szerokościach, repeat(3, 1fr) trzy kolumny równe, a 1fr 2fr dwie, z których druga jest dwa razy szersza.
Jednostka fr (fraction, część) dzieli WOLNE miejsce, czyli to, co zostało po odstępach i kolumnach o stałej szerokości. Dlatego 1fr 2fr daje jedną trzecią i dwie trzecie reszty, a nie 1 procent i 2 procent. Odstępy między komórkami ustawia gap, ta sama właściwość co we flexboksie.
Siatka o dwóch kolumnach 30 i 70 procent z liniami od 1 do 3: baner, menu i stopka biegną od linii 1 do 3, panel boczny stoi w kolumnie pierwszej, blok główny w drugiej
Blok można rozciągnąć na kilka komórek i służą do tego numery LINII siatki, nie numery kolumn. Linie liczy się od 1, od lewej krawędzi kontenera, więc siatka o dwóch kolumnach ma trzy linie pionowe, a o trzech kolumnach cztery. Zapis grid-column: 1 / 3 znaczy „od linii 1 do linii 3", czyli przez obie kolumny, a grid-row robi to samo w pionie. Tak właśnie na rysunku baner, menu i stopka biegną przez całą szerokość, panel boczny zajmuje kolumnę pierwszą (30 procent), a blok główny drugą (70 procent).
.galeria {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: 200px 200px;
gap: 10px;
}
.galeria .wyrozniony {
grid-column: 1 / 3;
grid-row: 1;
}
Drugi sposób opisania tej samej siatki jest czytelniejszy, bo zamiast liczyć linie, rysuje układ nazwami. grid-template-areas (szablon obszarów) przyjmuje po jednym ciągu znaków na każdy wiersz siatki, a w ciągu tyle nazw, ile jest kolumn. Nazwa powtórzona w sąsiednich komórkach zlepia je w jeden obszar. Potem każdy blok dostaje grid-area z nazwą swojego obszaru. Nazwy wymyślasz sam i piszesz je bez polskich znaków.
Układ z arkusza dwoma sposobami
Arkusz CKE rysuje układ sklepu prostokątami: baner na górze, pod nim menu, niżej panel boczny o szerokości 30 procent obok bloku głównego o szerokości 70 procent, na dole stopka. Struktura HTML jest gotowa z lekcji o znacznikach sekcji: <header>, <nav>, <aside>, <main> i <footer> stoją w pliku jeden pod drugim. Do tego samego wyniku prowadzą dwie drogi. Pierwsza to jeden grid na całym <body>, opisany obszarami. Nazwy obszarów układają się w rysunek: dwa razy baner w pierwszym wierszu znaczy, że baner idzie przez obie kolumny.
body {
display: grid;
grid-template-columns: 30% 70%;
grid-template-areas:
"baner baner"
"menu menu"
"panel glowny"
"stopka stopka";
gap: 10px;
}
header {
grid-area: baner;
}
nav {
grid-area: menu;
}
aside {
grid-area: panel;
}
main {
grid-area: glowny;
}
footer {
grid-area: stopka;
}
Druga droga używa flexboksa tylko tam, gdzie naprawdę są dwie kolumny, czyli w środkowym wierszu. Panel i blok główny trzeba wtedy opakować dodatkowym znacznikiem <div> z klasą, bo flexbox rozstawia wyłącznie dzieci jednego rodzica. Baner, menu i stopka zostają poza opakowaniem i same rozciągają się na całą szerokość, bo są blokami.
.srodek {
display: flex;
gap: 10px;
}
aside {
flex: 0 0 30%;
}
main {
flex: 1;
}
Wybór między nimi jest prosty. Flexbox bierzesz, gdy rozstawiasz elementy w JEDNYM kierunku: menu w rzędzie, dwie kolumny obok siebie, przyciski w linii, napis w środku banera. Grid bierzesz, gdy opisujesz całą stronę naraz i liczy się jednocześnie podział na kolumny i na wiersze. Przy układzie z czterech wierszy grid ma tę przewagę, że cały układ widać w jednym miejscu arkusza stylów.
Kolumny, pudełko i stary float
Szerokość kolumny liczy się razem z marginesami wewnętrznymi i obramowaniem, więc panel flex: 0 0 30% z obramowaniem 2 px zajmie w sumie więcej niż 30 procent, dopóki nie ustawisz box-sizing: border-box, o czym mówi lekcja o modelu pudełkowym. Starszy sposób budowania kolumn opisuje lekcja o właściwościach display, position i float: tam bloki spływają na bok, wypadają ze zwykłego przepływu i trzeba je posprzątać właściwością clear, żeby stopka nie wjechała pod kolumnę. Flexbox i grid tego kłopotu nie mają, bo bloki zostają w przepływie, a rodzic zna ich wymiary. Przy okazji znika problem równych wysokości kolumn. Domyślna wartość align-items: stretch rozciąga wszystkie elementy flex do wysokości najwyższego z nich, więc panel boczny z trzema wierszami tekstu sięga tak nisko jak blok główny z dziesięcioma i tło obu kończy się na tej samej wysokości. Przy float ten sam efekt wymagał sztuczek z tłem rodzica.
Na wąskim ekranie dwie kolumny trzeba złożyć jedna pod drugą i wystarczy do tego jedna deklaracja flex-direction: column wewnątrz reguły @media, co pokazuje lekcja o stronach responsywnych. Na egzaminie
Pytanie pisemne najczęściej pokazuje rysunek układu bloków ponumerowanych od 2 do 5 razem z kodem HTML i każe wskazać kod CSS, który taki układ daje. Odpowiedź czyta się z rysunku w dwóch krokach: policz, ile bloków stoi w jednym wierszu, i sprawdź ich szerokości. Trzy bloki obok siebie o równej szerokości to repeat(3, 1fr) albo trzy razy flex: 1, a blok wąski przy szerokim to para 30 i 70 procent. Drugi kształt to pojedyncza właściwość do rozpoznania: justify-content rozkłada elementy wzdłuż osi głównej, a nie wyrównuje ich w pionie, align-items działa w poprzek, a menu poziome z listy punktowanej robi właściwość display z wartością flex albo inline-block, nie position ani text-align.
Dwie odpowiedzi mylą się regularnie. display: flex przypisuje się RODZICOWI, więc reguła napisana dla li zamiast dla ul nie ustawi punktów w rzędzie. Jednostka fr to część wolnego miejsca, a nie procent szerokości ani piksele, więc kolumny 1fr 1fr obok kolumny 200px dzielą między siebie to, co zostanie po odjęciu tych 200 px i odstępów.
W zadaniu praktycznym oceniany jest wygląd, nie sposób jego uzyskania: arkusz przyjmie flexboksa, grid i float, o ile na ekranie powstanie układ z rysunku. Szerokości przepisuj dokładnie tak, jak podaje polecenie, czyli w procentach, jeśli arkusz pisze o procentach. Zanim zamkniesz plik, sprawdź trzy rzeczy: czy panel i blok główny naprawdę stoją obok siebie, czy ich proporcja zgadza się z rysunkiem i czy stopka jest pod OBIEMA kolumnami, a nie obok jednej z nich.
Ściąga
display: flex
rodzic układa dzieci w jednym wierszu obok siebie
flex-direction: column
oś główna staje się pionowa, elementy jeden pod drugim
justify-content: center
rozmieszczenie wzdłuż osi głównej, tu na środku
justify-content: space-between
pierwszy przy lewej krawędzi, ostatni przy prawej
align-items: center
wyrównanie wzdłuż osi poprzecznej, tu w pionie
align-items: stretch
wartość domyślna, kolumny mają równą wysokość
gap: 20px
odstęp między elementami, bez odstępu przy krawędziach
flex: 1
element dzieli wolne miejsce po równo z innymi
flex: 0 0 30%
element ma dokładnie 30 procent szerokości
display: grid
rodzic dzieli się na kolumny i wiersze siatki
grid-template-columns: 30% 70%
dwie kolumny: panel 30 procent, blok główny 70 procent
grid-template-columns: repeat(3, 1fr)
trzy kolumny dzielące wolne miejsce po równo
grid-column: 1 / 3
blok od linii 1 do linii 3, czyli przez dwie kolumny
grid-template-areas
rysunek układu nazwami obszarów, po ciągu na wiersz
grid-area: baner
przypisanie bloku do obszaru o tej nazwie
Pobierz ściągę PDF