Zawijanie siatki CSS

126

Czy można zawijać siatkę CSS bez używania zapytań o media?

W moim przypadku mam niedeterministyczną liczbę elementów, które chcę umieścić w siatce i chcę, aby ta siatka była zawijana. Używając Flexbox, nie mogę niezawodnie ładnie rozmieścić rzeczy. Chciałbym również uniknąć wielu zapytań o media.

Oto przykładowy kod :

.grid {
  display: grid;
  grid-gap: 10px;
  grid-auto-flow: column;
  grid-template-columns: 186px 186px 186px 186px;
}

.grid > * {
  background-color: green;
  height: 200px;
}
<div class="grid">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
</div>

A oto obraz GIF:

Obraz GIF przedstawiający to, co widzę

Na marginesie, jeśli ktoś może mi powiedzieć, jak mogę uniknąć określania szerokości wszystkich elementów, tak jak ja grid-template-columns, byłoby świetnie. Wolałbym, żeby dzieci określały własną szerokość.

kentcdodds
źródło
2
grid-template-columns: auto auto auto auto;działa w tym przypadku? =)
Jakub Chlebowicz

Odpowiedzi:

219

Użyj jednego auto-filllub auto-fitjako liczba powtórzeń w repeat()notacji.

repeat( [ <positive-integer> | auto-fill | auto-fit ] , <track-list> )

auto-fill

Gdy auto-filljako numer powtórzenia podano, jeśli pojemnik siatki ma określony rozmiar lub maksymalny rozmiar na odpowiedniej osi, to liczba powtórzeń jest największą możliwą liczbą całkowitą dodatnią, która nie powoduje przepełnienia siatki pojemnika siatki.

.grid {
  display: grid;
  grid-gap: 10px;
  grid-template-columns: repeat(auto-fill, 186px);
}

.grid>* {
  background-color: green;
  height: 200px;
}
<div class="grid">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
</div>

Siatka będzie powtarzać tyle ścieżek, ile to możliwe, bez przepełnienia swojego kontenera.

Używanie automatycznego wypełniania jako numeru powtórzenia notacji powtarzania ()

W tym przypadku, biorąc pod uwagę powyższy przykład (patrz ilustracja) , tylko 5 ścieżek może zmieścić się w kontenerze siatki bez przepełnienia. W naszej siatce są tylko 4 elementy, więc piąty jest tworzony jako pusty tor w pozostałej przestrzeni.

Reszta pozostałej przestrzeni, ścieżka nr 6, kończy jawną siatkę. Oznacza to, że nie było wystarczająco dużo miejsca, aby umieścić kolejny tor.


auto-fit

auto-fitKluczowe zachowuje się tak samo jak auto-fillz tym, że po algorytmu placement pozycja siatki żadnych pustych utworów w pozostałej przestrzeni będzie upadł 0.

.grid {
  display: grid;
  grid-gap: 10px;
  grid-template-columns: repeat(auto-fit, 186px);
}

.grid>* {
  background-color: green;
  height: 200px;
}
<div class="grid">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
</div>

Siatka będzie nadal powtarzać tyle ścieżek, ile to możliwe, bez przepełnienia swojego kontenera, ale puste ścieżki zostaną zwinięte do 0.

Zwinięty tor jest traktowany jako mający stałą funkcję zmiany rozmiaru 0px.

Używanie automatycznego dopasowania jako numeru powtórzenia notacji powtarzania ()

W przeciwieństwie do auto-fillprzykładu z obrazkiem, pusta piąta ścieżka jest zwinięta, co kończy jawną siatkę zaraz po czwartym elemencie.


auto-fill vs auto-fit

Różnica między nimi jest zauważalna, gdy minmax()używana jest funkcja.

Służy minmax(186px, 1fr)do określania zakresu elementów od 186pxdo 186pxplus ułamek pozostałego miejsca w kontenerze siatki.

Podczas używania auto-fillprzedmioty będą rosły, gdy nie będzie miejsca na umieszczenie pustych ścieżek.

.grid {
  display: grid;
  grid-gap: 10px;
  grid-template-columns: repeat(auto-fill, minmax(186px, 1fr));
}

.grid>* {
  background-color: green;
  height: 200px;
}
<div class="grid">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
</div>

Podczas używania auto-fitelementy będą rosły, aby wypełnić pozostałą przestrzeń, ponieważ wszystkie puste ścieżki są zwinięte 0px.

.grid {
  display: grid;
  grid-gap: 10px;
  grid-template-columns: repeat(auto-fit, minmax(186px, 1fr));
}

.grid>* {
  background-color: green;
  height: 200px;
}
<div class="grid">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
</div>


Plac zabaw:

CodePen

Sprawdzanie ścieżek automatycznego wypełniania

autouzupełnianie


Sprawdzanie torów autodopasowania

automatyczne dopasowanie

Ricky
źródło
3
Czy jest jakiś sposób, aby wyśrodkować te, które są w następnej linii?
kentcdodds
Tak jak w przypadku Flex Box, na display: gridelemencie użyjjustify-content: center
Spittal
Drogi @Ricky Jak sprawić, by pierwsza właściwość minmax np. repeat(auto-fill, minmax(186px, 1fr));nie jest pikselami, ale tak długo, jak długo element div zawiera tekst?
mesqueeb
1
@mesqueeb Nie jest to możliwe, potrzebny jest określony rozmiar. Możesz spojrzeć na odpowiedź, aby uzyskać więcej informacji.
Ricky
1
Czy jest jakiś sposób, aby to zrobić tak, że kiedy ma przejść do następnej linii, dwa elementy spadają zamiast tylko jednego? Więc jak od 4 do 2 do 1 i nie masz 4 do 3 do 2 do 1?
sammiepls
16

Albo chcesz auto-fitlub auto-fillwewnątrz repeat()funkcji:

grid-template-columns: repeat(auto-fit, 186px);

Różnica między nimi staje się widoczna, jeśli użyjesz również a, minmax()aby umożliwić elastyczne rozmiary kolumn:

grid-template-columns: repeat(auto-fill, minmax(186px, 1fr));

Dzięki temu kolumny mogą zmieniać rozmiar, od 186 pikseli do kolumn o równej szerokości rozciągających się na całej szerokości kontenera. auto-fillutworzy tyle kolumn, ile zmieści się na szerokości. Jeśli, powiedzmy, pasuje pięć kolumn, nawet jeśli masz tylko cztery elementy siatki, pojawi się piąta pusta kolumna:

Tutaj wprowadź opis obrazu

Użycie auto-fitzamiast tego zapobiegnie pustym kolumnom, rozciągając je dalej, jeśli to konieczne:

Tutaj wprowadź opis obrazu

keithjgrant
źródło
7

Możesz szukać auto-fill:

grid-template-columns: repeat(auto-fill, 186px);

Demo: http://codepen.io/alanbuchanan/pen/wJRMox

Aby efektywniej wykorzystać dostępne miejsce, możesz użyć minmaxi przekazać autojako drugi argument:

grid-template-columns: repeat(auto-fill, minmax(186px, auto));

Demo: http://codepen.io/alanbuchanan/pen/jBXWLR

Jeśli nie chcesz pustych kolumn, możesz użyć auto-fitzamiast auto-fill.

alanbuchanan
źródło
2
Czy jest jakiś sposób, aby wyśrodkować te, które są w następnej linii?
kentcdodds
3

Miałem podobną sytuację. Oprócz tego, co zrobiłeś, chciałem wyśrodkować moje kolumny w kontenerze, nie pozwalając pustym kolumnom na lewą lub prawą:

.grid { 
    display: grid;
    grid-gap: 10px;
    justify-content: center;
    grid-template-columns: repeat(auto-fit, minmax(200px, auto));
}
farrellw
źródło
Re „nie zezwalając im na puste kolumny” : Czy masz na myśli „nie zezwalając na puste kolumny także dla nich” ( abyteżteż )? Lub „nie zezwalając na puste kolumny” (bez opcji do )? Albo coś innego (to nie wydaje się obliczać)?
Peter Mortensen
1

Oto moja próba. Przepraszam za puch, czułam się wyjątkowo kreatywna.

Moja metoda to rodzic divo stałych wymiarach . Reszta to po prostu dopasowanie zawartości do tego elementu div.

Spowoduje to przeskalowanie obrazów niezależnie od proporcji. Nie będzie też twardego kadrowania .

body {
    background: #131418;
    text-align: center;
    margin: 0 auto;
}

.my-image-parent {
    display: inline-block;
    width: 300px;
    height: 300px;
    line-height: 300px; /* Should match your div height */
    text-align: center;
    font-size: 0;
}

/* Start demonstration background fluff */
    .bg1 {background: url(https://unsplash.it/801/799);}
    .bg2 {background: url(https://unsplash.it/799/800);}
    .bg3 {background: url(https://unsplash.it/800/799);}
    .bg4 {background: url(https://unsplash.it/801/801);}
    .bg5 {background: url(https://unsplash.it/802/800);}
    .bg6 {background: url(https://unsplash.it/800/802);}
    .bg7 {background: url(https://unsplash.it/802/802);}
    .bg8 {background: url(https://unsplash.it/803/800);}
    .bg9 {background: url(https://unsplash.it/800/803);}
    .bg10 {background: url(https://unsplash.it/803/803);}
    .bg11 {background: url(https://unsplash.it/803/799);}
    .bg12 {background: url(https://unsplash.it/799/803);}
    .bg13 {background: url(https://unsplash.it/806/799);}
    .bg14 {background: url(https://unsplash.it/805/799);}
    .bg15 {background: url(https://unsplash.it/798/804);}
    .bg16 {background: url(https://unsplash.it/804/799);}
    .bg17 {background: url(https://unsplash.it/804/804);}
    .bg18 {background: url(https://unsplash.it/799/804);}
    .bg19 {background: url(https://unsplash.it/798/803);}
    .bg20 {background: url(https://unsplash.it/803/797);}
/* end demonstration background fluff */

.my-image {
    width: auto;
    height: 100%;
    vertical-align: middle;
    background-size: contain;
    background-position: center;
    background-repeat: no-repeat;
}
<div class="my-image-parent">
    <div class="my-image bg1"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg2"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg3"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg4"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg5"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg6"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg7"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg8"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg9"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg10"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg11"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg12"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg13"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg14"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg15"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg16"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg17"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg18"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg19"></div>
</div>

<div class="my-image-parent">
    <div class="my-image bg20"></div>
</div>

I haz kode
źródło