Обтекание сетки CSS


126

Можно ли обернуть сетку CSS без использования медиа-запросов?

В моем случае у меня есть недетерминированное количество элементов, которые я хочу разместить в сетке, и я хочу, чтобы эта сетка обернулась. Используя Flexbox, я не могу надежно и красиво разместить вещи. Я бы тоже хотел избежать кучи медиа-запросов.

Вот пример кода :

.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>

А вот изображение в формате GIF:

GIF-изображение того, что я вижу

В качестве примечания, если бы кто-нибудь мог сказать мне, как я мог бы избежать указания ширины всех элементов, как я, grid-template-columnsэто было бы здорово. Я бы предпочел, чтобы дети указали свою ширину.


2
grid-template-columns: auto auto auto auto;работает в этом случае? =)
Якуб Хлебович

Ответы:


219

Используйте либо, auto-fillлибо auto-fitкак число повторения repeat()записи.

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

auto-fill

Когда auto-fillзадано как число повторений, если контейнер сетки имеет определенный размер или максимальный размер на соответствующей оси, то количество повторений является максимально возможным положительным целым числом, которое не приводит к переполнению сеткой своего контейнера сетки.

.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>

Сетка будет повторять столько треков, сколько возможно, не переполняя свой контейнер.

Использование автозаполнения в качестве номера повторения нотации repeat ()

В этом случае, учитывая приведенный выше пример (см. Изображение) , только 5 дорожек могут поместиться в грид-контейнер без переполнения. В нашей сетке всего 4 элемента, поэтому пятый создается как пустая дорожка в оставшемся пространстве.

Остальное оставшееся пространство, дорожка № 6, завершает явную сетку. Это означает, что не хватило места для размещения другой дорожки.


auto-fit

auto-fitКлючевое слово ведет себя так же , как auto-fill, за исключением того, что после алгоритма размещения элемент сетки либо пустые дорожки в пределах оставшегося пространства будут свернуты в 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>

Сетка по-прежнему будет повторять столько треков, сколько возможно, не переполняя свой контейнер, но пустые треки будут свернуты в 0 .

Свернутая дорожка рассматривается как имеющая фиксированную функцию определения размера дорожки 0px.

Использование автоподгонки в качестве номера повторения нотации repeat ()

В отличие от auto-fillпримера изображения, пустая пятая дорожка сворачивается, заканчивая явную сетку сразу после 4-го элемента.


auto-fill против auto-fit

Разница между ними заметна при использовании minmax()функции.

Используйте minmax(186px, 1fr)для изменения диапазона элементов от 186pxдо 186pxплюс часть оставшегося пространства в контейнере сетки.

При использовании auto-fillэлементы будут расти, если не будет места для размещения пустых дорожек.

.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>

При использовании auto-fitэлементы будут расти, чтобы заполнить оставшееся пространство, потому что все пустые дорожки свернуты 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>


Игровая площадка:

CodePen

Проверка треков автозаполнения

автозаполнение


Проверка автоподгонки гусениц

автоподгонка


3
Есть ли способ сделать так, чтобы он находился в центре тех, которые находятся на следующей строке?
kentcdodds

Как и в случае с гибкой коробкой, на display: gridэлементах используйтеjustify-content: center
Spittal

Уважаемый @Ricky Как сделать так, чтобы первое свойство minmax, например. repeat(auto-fill, minmax(186px, 1fr));это не пиксели, но до тех пор, пока внутри div есть текст?
mesqueeb

1
@mesqueeb Не возможно, нужен определенный размер. Вы можете взглянуть на этот ответ для получения более подробной информации.
Ricky

1
Есть ли способ сделать так, чтобы при переходе к следующей строке два элемента упали вместо одного? Итак, как от 4 до 2 к 1, а не от 4 до 3 до 2 к 1?
sammiepls

16

Вы хотите либо auto-fitили auto-fillвнутри repeat()функции:

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

Разница между ними становится очевидной, если вы также используете a, minmax()чтобы разрешить гибкие размеры столбцов:

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

Это позволяет вашим столбцам изменяться по размеру, от 186 пикселей до столбцов одинаковой ширины, растягивающихся по всей ширине контейнера. auto-fillсоздаст столько столбцов, сколько поместится по ширине. Если, скажем, уместится пять столбцов, даже если у вас всего четыре элемента сетки, будет пятый пустой столбец:

Введите описание изображения здесь

Использование auto-fitвместо этого предотвратит пустые столбцы, при необходимости растягивая ваши:

Введите описание изображения здесь


7

Вы можете искать auto-fill:

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

Демо: http://codepen.io/alanbuchanan/pen/wJRMox

Чтобы использовать доступное пространство более эффективно, вы можете использовать minmaxи передать в autoкачестве второго аргумента:

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

Демо: http://codepen.io/alanbuchanan/pen/jBXWLR

Если вам не нужны пустые столбцы, вы можете использовать auto-fitвместо auto-fill.


2
Есть ли способ сделать так, чтобы он находился в центре тех, которые находятся на следующей строке?
kentcdodds

3

У меня была похожая ситуация. Вдобавок к тому, что вы сделали, я хотел центрировать свои столбцы в контейнере, не позволяя пустым столбцам перемещаться влево или вправо:

.grid { 
    display: grid;
    grid-gap: 10px;
    justify-content: center;
    grid-template-columns: repeat(auto-fit, minmax(200px, auto));
}

Re "не разрешая пустые столбцы для них" : Вы имеете в виду "не разрешая пустые столбцы ни для них" ( втожени )? Или «не позволяя пустые столбцы для них» (без к )? Или что-то еще (кажется, не вычисляет)?
Питер Мортенсен

1

Вот моя попытка. Простите за пух, я чувствовал себя более креативным.

Мой метод - это родитель divс фиксированными размерами . Остальное просто соответствует содержимому этого div.

Это изменит масштаб изображения независимо от соотношения сторон. Там не будет никакого жесткого подрезания либо.

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>

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.