13.8. Automatyczne umieszczanie: grid-auto-flow
Jak Grid umieszcza elementy domyślnie?
Gdy mamy więcej elementów Grid niż zdefiniowanych jawnie miejsc (za pomocą linii lub obszarów), Grid musi zdecydować, gdzie umieścić te pozostałe, **automatycznie umieszczane** elementy.
Domyślnie, Grid umieszcza elementy w kolejnych pustych komórkach, wypełniając siatkę **wiersz po wierszu**, od lewej do prawej (w językach LTR). Jeśli wiersz się zapełni, przechodzi do następnego.
Właściwość grid-auto-flow
pozwala kontrolować ten proces automatycznego umieszczania. Stosuje się ją do **kontenera Grid**.
Wartości grid-auto-flow
Właściwość ta kontroluje dwa aspekty: kierunek przepływu oraz algorytm wypełniania luk.
row
(wartość domyślna): Automatycznie umieszczane elementy wypełniają kolejne komórki w **wierszu**. Jeśli w bieżącym wierszu nie ma już miejsca, tworzony jest nowy wiersz (lub używany jest następny zdefiniowany wiersz).column
: Automatycznie umieszczane elementy wypełniają kolejne komórki w **kolumnie**. Jeśli w bieżącej kolumnie nie ma już miejsca, tworzona jest nowa kolumna (lub używana jest następna zdefiniowana kolumna).dense
: To słowo kluczowe można dodać dorow
lubcolumn
(np.grid-auto-flow: row dense;
lubgrid-auto-flow: column dense;
). Włącza ono algorytm "gęstego" pakowania. Jeśli późniejszy element jest mniejszy i może zmieścić się we wcześniejszej luce pozostawionej przez większy element, algorytmdense
spróbuje go tam umieścić, potencjalnie zmieniając wizualną kolejność elementów w stosunku do ich kolejności w DOM.
Przykład: row
vs column
<div class="container row-flow">
<div class="item item-1">1</div>
<div class="item item-2" style="grid-column: span 2;">2 (span 2)</div>
<div class="item item-3">3</div>
<div class="item item-4">4</div>
</div>
<div class="container column-flow">
<div class="item item-1">1</div>
<div class="item item-2" style="grid-row: span 2;">2 (span 2)</div>
<div class="item item-3">3</div>
<div class="item item-4">4</div>
</div>
.container {
display: grid;
grid-template-columns: repeat(3, 80px);
grid-template-rows: repeat(3, 60px);
gap: 5px;
border: 1px solid black;
margin-bottom: 15px;
}
.item {
background-color: lightblue;
border: 1px solid navy;
display: flex; justify-content: center; align-items: center;
}
.item-2 { background-color: lightcoral; }
.row-flow { grid-auto-flow: row; } /* Domyślnie */
.column-flow { grid-auto-flow: column; }
Efekt wizualny:
grid-auto-flow: row;
(domyślnie)
Element 1 w [1,1]. Element 2 zajmuje [1,2] i [1,3]. Element 3 przechodzi do następnego wiersza [2,1]. Element 4 w [2,2].
grid-auto-flow: column;
Element 1 w [1,1]. Element 2 zajmuje [2,1] i [3,1]. Element 3 przechodzi do następnej kolumny [1,2]. Element 4 w [2,2].
Algorytm dense
Algorytm dense
próbuje wypełnić luki w siatce, które mogły powstać przez umieszczenie większych elementów. Może to spowodować, że elementy pojawią się wizualnie w innej kolejności niż w kodzie HTML.
<div class="container dense-flow">
<div class="item item-1" style="grid-column: span 2;">1 (span 2)</div>
<div class="item item-2">2</div>
<div class="item item-3">3</div>
<div class="item item-4">4</div>
</div>
.dense-flow {
display: grid;
grid-template-columns: repeat(3, 80px);
grid-template-rows: repeat(3, 60px);
gap: 5px;
border: 1px solid black;
grid-auto-flow: row dense; /* Włącz gęste pakowanie wierszami */
}
/* Style .item jak poprzednio */
.item-1 { background-color: lightcoral; }
Efekt wizualny (row dense
):
Bez dense
: Element 1 zajmuje [1,1] i [1,2]. Element 2 zajmuje [1,3]. Element 3 przechodzi do [2,1]. Element 4 do [2,2]. Komórka [2,3] pozostaje pusta.
Z dense
: Element 1 zajmuje [1,1] i [1,2]. Element 2 normalnie trafiłby do [1,3]. Element 3 normalnie trafiłby do [2,1]. Ale algorytm dense
zauważa, że element 2 (który zajmuje 1 komórkę) zmieści się w luce [1,3] - umieszcza go tam. Następnie element 3 trafia do [2,1], a element 4 do [2,2]. Efekt końcowy jest taki sam jak bez dense w tym konkretnym przypadku, ale gdyby element 2 był większy, a 3 mniejszy, 3 mógłby wskoczyć w lukę przed 2.
Uwaga: Używanie dense
może poprawić wykorzystanie przestrzeni, ale potencjalnie kosztem logiki wizualnej kolejności, co może być problematyczne dla dostępności, podobnie jak właściwość order
we Flexboxie.
Zadania praktyczne
Zadanie 1 (z rozwiązaniem)
Stwórz siatkę 4x3. Ustaw grid-auto-flow: column;
. Dodaj 8 elementów. Zaobserwuj, jak wypełniają siatkę kolumna po kolumnie.
Rozwiązanie:
HTML (8 elementów):
<div class="container-task1">
<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 class="item">6</div><div class="item">7</div><div class="item">8</div>
</div>
CSS:
.container-task1 {
display: grid;
grid-template-columns: repeat(4, 60px);
grid-template-rows: repeat(3, 50px);
gap: 5px;
border: 1px solid black;
grid-auto-flow: column; /* Wypełniaj kolumnami */
}
.item {
background-color: lightblue;
border: 1px solid navy;
display: flex; justify-content: center; align-items: center;
}
Efekt: Elementy 1, 2, 3 wypełnią pierwszą kolumnę. Elementy 4, 5, 6 wypełnią drugą. Elementy 7, 8 wypełnią początek trzeciej kolumny.
Zadanie 2 (do samodzielnego wykonania)
Stwórz siatkę 3x3. Dodaj 5 elementów. Pierwszy element niech zajmuje 2 kolumny (grid-column: span 2;
). Ustaw grid-auto-flow: row dense;
. Zaobserwuj, czy i jak algorytm dense
wypełnia ewentualne luki.
Zadanie 3 (do samodzielnego wykonania)
Stwórz siatkę 2x4. Ustaw grid-auto-flow: column dense;
. Dodaj 6 elementów, gdzie drugi element zajmuje 2 wiersze (grid-row: span 2;
). Zaobserwuj efekt.
FAQ - Najczęściej zadawane pytania
Jaka jest domyślna wartość grid-auto-flow
?
Domyślną wartością jest row
. Oznacza to, że automatycznie umieszczane elementy domyślnie wypełniają siatkę wiersz po wierszu.
Czy dense
zawsze zmienia kolejność wizualną?
Nie zawsze. Algorytm dense
zmienia kolejność tylko wtedy, gdy znajdzie lukę we wcześniejszej części siatki, w którą może wpasować mniejszy element umieszczany później. Jeśli takich luk nie ma lub elementy nie pasują, kolejność pozostanie taka sama jak bez dense
.
Jak grid-auto-flow
współgra z jawnie umieszczonymi elementami?
grid-auto-flow
dotyczy tylko elementów, które **nie mają** jawnie określonego położenia za pomocą grid-column
, grid-row
lub grid-area
. Jawnie umieszczone elementy zawsze trafiają tam, gdzie zostały wskazane, a algorytm automatycznego umieszczania wypełnia pozostałe wolne komórki.
Czy powinienem używać dense
?
Używaj dense
ostrożnie. Jest przydatne w układach, gdzie wizualna kolejność nie jest kluczowa, a maksymalne wykorzystanie przestrzeni jest priorytetem (np. galerie zdjęć o różnych rozmiarach). Unikaj go, jeśli logiczna kolejność odczytu lub nawigacji (np. klawiaturą) jest ważna, ponieważ zmiana kolejności wizualnej może wprowadzać użytkowników w błąd.