TL;DR
Jeśli znasz flexbox, Grid powinien być Ci znajomy. Rachel Andrew prowadzi świetną witrynę poświęconą CSS Grid, która pomoże Ci zacząć. Sieć jest teraz dostępna w Google Chrome.
Flexbox? Siatka?
W ciągu ostatnich kilku lat Flexbox w CSS stał się powszechnie stosowany, a obsługa w przeglądarkach wygląda naprawdę dobrze (chyba że należysz do nieszczęśników, którzy muszą obsługiwać IE9 i starsze wersje). Flexbox ułatwił wiele złożonych zadań związanych z układem, takich jak równomierne rozmieszczenie elementów, układy od góry do dołu czy święty Graal szaleńców od CSS: wyśrodkowanie pionowe.
Niestety ekrany mają zwykle drugi wymiar, o który musimy się martwić. Oprócz samodzielnego określania rozmiarów elementów nie możesz jednocześnie stosować rytmu pionowego i poziomego, korzystając tylko z flexboxa. W takich przypadkach z pomocą przychodzi CSS Grid.
Od ponad 5 lat pracujemy nad siatką CSS, która jest dostępna w większości przeglądarek za pomocą flagi, a dodatkowy czas poświęciliśmy na interoperacyjność, aby uniknąć problemów z wdrożeniem, jakie miało miejsce w przypadku Flexboxa. Jeśli więc zastosujesz układ siatki w Chrome, prawdopodobnie uzyskasz ten sam wynik w Firefoksie i Safari. W momencie pisania tego artykułu implementacja Grida w Microsoft Edge jest nieaktualna (ta sama, która była już dostępna w IE11), a aktualizacja jest „rozważana”.
Pomimo podobieństwa koncepcji i składni nie traktuj Flexboxa i Grida jako konkurencyjnych technik układu. Siatka układa elementy w 2 wymiarach, a Flexbox – w 1 wymiarze. Połączenie tych dwóch narzędzi daje efekt synergii.
Definiowanie siatki
Aby zapoznać się z poszczególnymi właściwościami Grida, gorąco polecam Grid By Example Rachel Andrew lub Cheat Sheet CSS Tricks. Jeśli znasz flexbox, wiele właściwości i ich znaczenie powinno być Ci znane.
Przyjrzyjmy się standardowemu układowi siatki z 12 kolumnami. Klasyczny układ z 12 kolumnami jest popularny, ponieważ liczba 12 jest podzielna przez 2, 3, 4 i 6, a zatem przydaje się w wielu projektach. Zastosujmy ten układ:
Zacznijmy od kodu znacznika:
<!DOCTYPE html>
<body>
<header></header>
<nav></nav>
<main></main>
<footer></footer>
</body>
W naszej stylesheet zaczynamy od rozszerzenia elementu body
, aby obejmował cały widok, i przekształcamy go w kontener siatki:
html, body {
width: 100vw;
min-height: 100vh;
margin: 0;
padding: 0;
}
body {
display: grid;
}
Obecnie używamy CSS Grid. Hurra!
Następnym krokiem jest zaimplementowanie wierszy i kolumn siatki. Moglibyśmy zaimplementować wszystkie 12 kolumn w naszym makiety, ale ponieważ nie używamy wszystkich kolumn, spowodowałoby to niepotrzebne zaśmiecenie kodu CSS. Dla uproszczenia wdrożenie tego układu będzie wyglądać tak:
Szerokość nagłówka i stopki jest zmienna, a zawartość ma zmienną szerokość i wysokość. Nawigacja będzie zmienna w obu wymiarach, ale narzucimy na nią minimalną szerokość 200 pikseli. (Dlaczego? Aby pokazać funkcje CSS Grid, oczywiście.
W CSS Grid zestaw kolumn i wierszy nazywa się ścieżkami. Zacznijmy od zdefiniowania pierwszego zestawu ścieżek, czyli wierszy:
body {
display: grid;
grid-template-rows: 150px auto 100px;
}
Funkcja grid-template-rows
przyjmuje sekwencję rozmiarów, które definiują poszczególne wiersze.
W tym przypadku pierwsza linia ma wysokość 150 pikseli, a ostatnia – 100 pikseli.
Środkowy rząd ma wartość auto
, co oznacza, że dostosuje się do niezbędnej wysokości, aby pomieścić elementy siatki (podrzędne kontenera siatki) w tym rzędzie. Ponieważ nasze ciało jest rozciągnięte na cały widok, ścieżka zawierająca zawartość (żółta na powyższym obrazku) wypełni przynajmniej całą dostępną przestrzeń, ale w razie potrzeby rozrośnie się (i spowoduje przewijanie dokumentu).
W przypadku kolumn chcemy zastosować bardziej dynamiczne podejście: chcemy, aby nawigacja i treści się powiększały (i zmniejszały), ale aby nawigacja nigdy nie była mniejsza niż 200 pikseli, a treści były większe niż nawigacja. W Flexbox używamy atrybutów flex-grow i flex-shrink, ale w przypadku siatki jest to nieco inne:
body {
display: grid;
grid-template-rows: 150px auto 100px;
grid-template-columns: minmax(200px, 3fr) 9fr;
}
Definiujemy 2 kolumny. Pierwsza kolumna jest zdefiniowana za pomocą funkcji minmax()
, która przyjmuje 2 wartości: minimalny i maksymalny rozmiar danego utworu.
(To połączenie min-width
i max-width
). Jak już wspomnieliśmy, minimalna szerokość to 200 pikseli. Maksymalna szerokość to 3fr
. fr
to jednostka specyficzna dla siatki, która umożliwia rozłożenie dostępnej przestrzeni na elementy siatki. fr oznacza prawdopodobnie „fraction unit” (jednostka ułamkowa), ale może też oznaczać „free unit soon” (wkrótce bezpłatna jednostka).
Oznacza to, że obie kolumny będą się rozszerzać, aby wypełnić ekran, ale kolumna treści będzie zawsze 3 razy szersza niż kolumna nawigacji (pod warunkiem, że kolumna nawigacji będzie szersza niż 200 pikseli).
Umieszczenie elementów siatki nie jest jeszcze prawidłowe, ale rozmiar wierszy i kolumn jest prawidłowy i zachowuje się zgodnie z oczekiwaniami:
Umieszczanie elementów
Jedną z najpotężniejszych funkcji siatki jest możliwość umieszczania elementów bez względu na kolejność w DOM. (Pamiętaj jednak, że czytniki ekranu nawigują po DOM-ie, więc aby zapewnić prawidłową dostępność, musisz zwracać uwagę na to, jak zmieniasz kolejność elementów). Jeśli nie ustawisz ręcznego rozmieszczenia, elementy zostaną umieszczone w siatce w kolejności DOM, od lewej do prawej i od góry do dołu. Każdy element zajmuje 1 komórkę. Kolejność wypełniania siatki można zmienić za pomocą grid-auto-flow
.
Jak więc umieszczać elementy? Najprostszym sposobem umieszczania elementów siatki jest określenie, które kolumny i wiersze mają one obejmować. Do tego celu możesz użyć 2 składni: W pierwszej definiujesz punkty początkowy i końcowy. W drugim określasz punkt początkowy i zakres:
header {
grid-column: 1 / 3;
}
nav {
grid-row: 2 / span 2;
}
Chcemy, aby nagłówek zaczynał się w pierwszej kolumnie i kończył przed 3 kolumną. Nawigacja powinna zaczynać się w 2. wierszu i zajmować łącznie 2 wiersze.
Z technicznego punktu widzenia skończyliśmy już implementację układu, ale chcę pokazać Ci kilka funkcji, które Grid udostępnia, aby ułatwić Ci umieszczanie elementów. Pierwsza funkcja to możliwość nazywania krawędzi ścieżki i używania tych nazw do umieszczania:
body {
display: grid;
grid-template-rows: 150px [nav-start] auto 100px [nav-end];
grid-template-columns: [header-start] minmax(200px, 3fr) 9fr [header-end];
}
header {
grid-column: header-start / header-end;
}
nav {
grid-row: nav-start / nav-end;
}
Powyższy kod spowoduje zastosowanie tego samego układu co poprzedni kod.
Jeszcze bardziej przydatna jest funkcja nazywania całych regionów w siatce:
body {
display: grid;
grid-template-rows: 150px auto 100px;
grid-template-columns: minmax(200px, 3fr) 9fr;
grid-template-areas: "header header"
"nav content"
"nav footer";
}
header {
grid-area: header;
}
nav {
grid-area: nav;
}
Funkcja grid-template-areas
przyjmuje ciąg nazw oddzielonych spacjami, co pozwala deweloperowi nadać nazwę każdej komórce. Jeśli 2 sąsiednie komórki mają tę samą nazwę, zostaną połączone w jedną komórkę. Dzięki temu możesz dodać więcej semantyki do kodu układu i sprawić, że zapytania o media będą bardziej intuicyjne. Ten kod wygeneruje ten sam układ co poprzednio.
Czy chcesz dowiedzieć się więcej?
Tak, jest ich o wiele za dużo, aby można było omówić je w jednym poście na blogu. Rachel Andrew, która jest też GDE, jest zaproszonym ekspertem w grupie roboczej CSS i od samego początku współpracuje z tą grupą, aby uprościć projektowanie stron internetowych. Napisała nawet książkę na ten temat. Jej strona Grid By Example (po angielsku) to cenna pomoc w zapoznaniu się z Grid. Wiele osób uważa, że Grid to rewolucyjny krok w projektowaniu stron internetowych. Jest on teraz domyślnie włączony w Chrome, więc możesz zacząć z niego korzystać już dziś.