Kurs HTML

13.8. Automatyczne umieszczanie: grid-auto-flow

Strona główna > Kurs CSS > Rozdział 13: Grid Layout > 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ć do row lub column (np. grid-auto-flow: row dense; lub grid-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, algorytm dense 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)

1
2 (span 2)
3
4

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;

1
2 (span 2)
3
4

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):

1 (span 2)
2
3
4

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.