Лучший способ установить расстояние между элементами flexbox

Чтобы установить минимальное расстояние между элементами flexbox, я использую margin: 0 5px в .item и margin: 0 -5px в контейнере. Для меня это похоже на хак, но я не могу найти лучшего способа сделать это.

Пример

#box {
  display: flex;
  width: 100px;
  margin: 0 -5px;
}
.item {
  background: gray;
  width: 50px;
  height: 50px;
  margin: 0 5px;
}
<div id='box'>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
</div>

Ответ 1

  • Flexbox не имеет разрушающихся полей.
  • Во Flexbox нет ничего похожего на border-spacing для таблиц (за исключением свойства CSS gap, которое плохо поддерживается в большинстве браузеров, caniuse)

Поэтому добиться того, о чем вы просите, немного сложнее.

По моему опыту, "самым чистым" способом, который не использует :first-child/:last-child и работает без каких-либо изменений в flex-wrap:wrap, является установка padding:5px для контейнера и margin:5px для дочерних элементов. Это создаст разрыв 10px между каждым ребенком и между каждым ребенком и его родителем.

Демо

.upper
{
  margin:30px;
  display:flex;
  flex-direction:row;
  width:300px;
  height:80px;
  border:1px red solid;

  padding:5px; /* this */
}

.upper > div
{
  flex:1 1 auto;
  border:1px red solid;
  text-align:center;

  margin:5px;  /* and that, will result in a 10px gap */
}

.upper.mc /* multicol test */
{flex-direction:column;flex-wrap:wrap;width:200px;height:200px;}
<div class="upper">
  <div>aaa<br/>aaa</div>
  <div>aaa</div>
  <div>aaa<br/>aaa</div>
  <div>aaa<br/>aaa<br/>aaa</div>
  <div>aaa</div>
  <div>aaa</div>
</div>

<div class="upper mc">
  <div>aaa<br/>aaa</div>
  <div>aaa</div>
  <div>aaa<br/>aaa</div>
  <div>aaa<br/>aaa<br/>aaa</div>
  <div>aaa</div>
  <div>aaa</div>
</div>

Ответ 2

Это не взломать. Тот же метод также используется бутстрапом и его сеткой, однако вместо поля, bootstrap использует отступы для своих столбцов.

.row {
  margin:0 -15px;
}
.col-xx-xx {
  padding:0 15px;
}

Ответ 3

flexbox и css calc()

Здравствуйте, ниже мое рабочее решение для всех браузеров, поддерживающих flexbox. Нет отрицательных полей, нет хаков, нет обходных путей, чистый Css.

Демонстрация скрипки

   
.flexbox {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: space-between;
}

.flexbox > div {
  /*
    1/3  - 3 columns per row
    10px - spacing between columns 
  */
  box-sizing: border-box;
  margin-bottom: 10px;
  outline: 1px dotted red;
  width: calc(1/3*100% - (1 - 1/3)*10px);
}
<div class="flexbox">
  <div>col</div>
  <div>col</div>
  <div>col</div>
  <div>col</div>
  <div>col</div>
  <div>col</div>
</div>

Ответ 4

Вы можете использовать прозрачные границы.

Я рассматривал эту проблему, пытаясь построить модель гибкой сетки, которая может отбросить на таблицу + модель таблицы для старых браузеров. И Границы для сточных канавок казались мне лучшим выбором. т.е. таблицы-ячейки не имеют полей.

например.

.column{
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 10px solid transparent;
}

Также обратите внимание, что вам нужно min-width: 50px; для flexbox. Модель flex не будет обрабатывать фиксированные размеры, если вы не сделаете flex: none; на конкретном дочернем элементе, который вы хотите как фиксированный, и поэтому исключен из "flexi". http://jsfiddle.net/GLpUp/4/ Но все столбцы вместе с flex:none; больше не являются гибкой моделью. Вот что-то ближе к гибкой модели: http://jsfiddle.net/GLpUp/5/

Таким образом, вы можете использовать поля обычно, если вам не нужна резервная копия таблицы для старых браузеров. http://jsfiddle.net/GLpUp/3/

Настройка background-clip: padding-box; будет необходима при использовании фона, так как в противном случае фон будет проходить в прозрачную область границы.

Ответ 5

Это будет работать во всех случаях, даже если имеется несколько строк или любое количество элементов.

Мы используем display: grid;

#box {
  display: grid;
  width: 100px;
  grid-gap: 5px;
  /* Space between items */
  grid-template-columns: 1fr 1fr 1fr 1fr;
  /* Decide the number of columns and size */
}

.item {
  background: gray;
  width: 100%;
  /* width is not necessary only added this to understand that width works as 100% to the grid template allocated space **DEFAULT WIDTH WILL BE 100%** */
  height: 50px;
}
<div id='box'>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
</div>

Ответ 6

Вы можете использовать & > * + * в качестве селектора для эмуляции flex-gap (для одной строки):

#box { display: flex; width: 230px; outline: 1px solid blue; }
.item { background: gray; width: 50px; height: 100px; }

/* ----- Flexbox gap: ----- */

#box > * + * {
  margin-left: 10px;
}
<div id='box'>
    <div class='item'></div>
    <div class='item'></div>
    <div class='item'></div>
    <div class='item'></div>
</div>

Ответ 7

Допустим, если вы хотите установить 10px пробел между элементами, вы можете просто установить .item {margin-right:10px;} для всех и сбросить его на последний .item:last-child {margin-right:0;}

Вы также можете использовать общий селектор братьев ~ или next + sibling, чтобы установить левое поле для элементов, исключая первый .item ~.item {margin-left:10px;} или использовать .item:not(:last-child) {margin-right: 10px;}

Flexbox настолько умен, что он автоматически пересчитывает и равномерно распределяет сетку.

body {
  margin: 0;
}

.container {
  display: flex;
}

.item {
  flex: 1;
  background: gray;
  height: 50px;
}

.item:not(:last-child) {
  margin-right: 10px;
}
<div class="container">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

Ответ 8

Я нашел решение, основанное на общем родном селекторе ~ и допускающее бесконечное вложение.

См. этот код пера для рабочего примера

По сути, внутри контейнеров столбцов каждый дочерний элемент, которому предшествует другой дочерний элемент, получает верхнее поле. Аналогично, внутри каждого контейнера строк каждый дочерний элемент, которому предшествует другой, получает левое поле.

.box {
  display: flex;
  flex-grow: 1;
  flex-shrink: 1;
}

.box.columns {
  flex-direction: row;
}

.box.columns>.box~.box {
  margin-left: 5px;
}

.box.rows {
  flex-direction: column;
}

.box.rows>.box~.box {
  margin-top: 5px;
}
<div class="box columns">
  <div class="box" style="background-color: red;"></div>
  <div class="box rows">
    <div class="box rows">
      <div class="box" style="background-color: blue;"></div>
      <div class="box" style="background-color: orange;"></div>
      <div class="box columns">
        <div class="box" style="background-color: yellow;"></div>
        <div class="box" style="background-color: pink;"></div>
      </div>
    </div>
    <div class="box" style="background-color: green;"></div>
  </div>
</div>

Ответ 9

Переход от ответа на пишу, здесь немного улучшенная версия, которая позволяет установить фиксированное расстояние между элементами без окружающего поля.

http://jsfiddle.net/chris00/s52wmgtq/49/

Также включена версия Safari "-webkit-flex".

.outer1 {
    background-color: orange;
    padding: 10px;
}

.outer0 {
    background-color: green;
    overflow: hidden;
}

.container
{
    display: flex;
    display: -webkit-flex;
    flex-wrap: wrap;    
    -webkit-flex-wrap: wrap;
    background-color: rgba(0, 0, 255, 0.5);
    margin-left: -10px;
    margin-top: -10px;
}

.item
{
    flex-grow: 1;
    -webkit-flex-grow: 1;
    background-color: rgba(255, 0, 0, 0.5);
    width: 100px;
    padding: 10px;
    margin-left: 10px;
    margin-top: 10px;
    text-align: center;
    color: white;
}

<div class="outer1">
    <div class="outer0">
        <div class="container">
            <div class="item">text</div>
            <div class="item">text</div>
            <div class="item">text</div>
            <div class="item">text</div>
            <div class="item">text</div>
            <div class="item">text</div>
        </div>
    </div>
</div>

Ответ 10

Я использовал это для столбцов завершенной и фиксированной ширины. Ключ здесь calc()

Пример SCSS

$gap: 10px;

dl {
  display: flex;
  flex-wrap: wrap;
  padding: $gap/2;

  dt, dd {
    margin: $gap/2;}

  dt { // full width, acts as header
    flex: 0 0 calc(100% - #{$gap});}

  dd { // default grid: four columns 
    flex: 0 0 calc(25% - #{$gap});}

  .half { // hall width columns
    flex: 0 0 calc(50% - #{$gap});}

}

Полный образец Codepen

Ответ 11

Гибкий контейнер с маркером -x (отрицательный) и гибкими элементами с добавлением x (положительного) поля или приводит к желаемому визуальному результату: элементы Flex имеют фиксированный зазор 2x только между.

Кажется, что это просто вопрос предпочтения, следует ли использовать маржи или отступы для элементов flex.

В этом примере гибкие элементы масштабируются динамически, чтобы сохранить фиксированный зазор:

.flex-container { 
  margin: 0 -5px;
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

.flex-item {
  margin: 0 5px; // Alternatively: padding: 0 5px;
  flex: 1 0 auto;
}

Ответ 12

В конце концов они добавят свойство gap в flexbox. До тех пор вы могли бы использовать CSS-сетку, которая уже имеет свойство gap, и просто иметь одну строку. Ничуть, чем иметь дело с полями.

Ответ 13

При использовании flexbox создание желобов - это боль, особенно при обертывании.

Вам необходимо использовать отрицательные поля (, как показано в вопросе):

#box {
  display: flex;
  width: 100px;
  margin: 0 -5px;
}

... или измените HTML (, как показано в другом ответе):

<div class='flex-wrapper'>
  <div class='flex'>
    <div class='box'></div>
    <div class='box'></div>
            ...
  </div>
</div>

... или что-то еще.

В любом случае, вам нужен отвратительный взлом, чтобы заставить его работать, потому что flexbox не предоставляет функцию "flex-gap" (по крайней мере, пока).

Однако проблема с желобами проста и удобна с помощью CSS Grid Layout.

Спецификация Grid предоставляет свойства, которые создают пространство между элементами сетки, игнорируя пространство между элементами и контейнером. Эти свойства:

  • grid-column-gap
  • grid-row-gap
  • grid-gap (сокращение для обоих свойств выше)

Недавно спецификация была обновлена в соответствии с CSS-модулем выравнивания блоков, который предоставляет набор свойств выравнивания для использования во всех блочных моделях. Итак, свойства сейчас:

  • column-gap
  • row-gap
  • gap (стенография)

Однако не все браузеры с поддержкой Grid поддерживают новые свойства, поэтому я буду использовать оригинальные версии в демонстрационной версии ниже.

Кроме того, если необходим интервал между элементами и контейнером, padding на контейнере работает просто отлично (см. третий пример в демонстрационном примере ниже).

Из спецификации:

10.1. Gutters: the row-gap, column-gap, и gap properties

Свойства row-gap и column-gap (и их сокращение gap), когда указано на сетке контейнера, определить желоба между сеткой строки и столбцы сетки. Их синтаксис определен в CSS Box Alignment 3 §8 Разрывы между ящиками.

Эффект этих свойств, как будто затронутые линии сетки приобретенная толщина: дорожка сетки между двумя линиями сетки - это пространство между желобами, которые их представляют.

.box {
  display: inline-grid;
  grid-auto-rows: 50px;
  grid-template-columns: repeat(4, 50px);
  border: 1px solid black;
}

.one {
  grid-column-gap: 5px;
}

.two {
  grid-column-gap: 10px;
  grid-row-gap: 10px;
}

.three {
  grid-gap: 10px;
  padding: 10px;
}

.item {
  background: lightgray;
}
<div class='box one'>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
</div>

<hr>

<div class='box two'>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
</div>

<hr>

<div class='box three'>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
</div>

Ответ 14

Почему бы не сделать это так:

.item + .item {
    margin-left: 5px;
}

Это использует смежный селектор, чтобы дать все элементы .item, кроме первого a margin-left. Благодаря flexbox, это даже приводит к одинаково широким элементам. Это также можно сделать с помощью вертикально расположенных элементов и margin-top, конечно.

Ответ 15

Здесь мое решение, которое не требует установки каких-либо классов на дочерние элементы:

.flex-inline-row {
    display: inline-flex;
    flex-direction: row;
}

.flex-inline-row.flex-spacing-4px > :not(:last-child) {
    margin-right: 4px;
}

Использование:

<div class="flex-inline-row flex-spacing-4px">
  <span>Testing</span>
  <span>123</span>
</div>

Тот же метод можно использовать для обычных строк и столбцов гибкости в дополнение к приведенному выше примеру строки и расширен с классами для интервала, отличного от 4px.

Ответ 16

Используя Flexbox в моем решении, я использовал свойство justify-content для родительского элемента (контейнера), и я указал поля внутри свойства flex-basis элементов. Проверьте фрагмент кода ниже:

.container {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-around;
  margin-bottom: 10px;
}

.item {
  height: 50px;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #999;
}

.item-1-4 {
  flex-basis: calc(25% - 10px);
}

.item-1-3 {
  flex-basis: calc(33.33333% - 10px);
}

.item-1-2 {
  flex-basis: calc(50% - 10px);
}
<div class="container">
  <div class="item item-1-4">1</div>
  <div class="item item-1-4">2</div>
  <div class="item item-1-4">3</div>
  <div class="item item-1-4">4</div>
</div>
<div class="container">
  <div class="item item-1-3">1</div>
  <div class="item item-1-3">2</div>
  <div class="item item-1-3">3</div>
</div>
<div class="container">
  <div class="item item-1-2">1</div>
  <div class="item item-1-2">2</div>
</div>

Ответ 17

Я часто использую оператор + для таких случаев

#box {
  display: flex;
  width: 100px;
}
.item {
  background: gray;
  width: 50px;
  height: 50px;
}
.item + .item {
    margin-left: 5px;
}
<div id='box'>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
</div>

Ответ 18

Columnify - класс соло для N столбцов

Flexbox и SCSS

.columnify {
  display: flex;

  > * {
    flex: 1;

    &:not(:first-child) {
      margin-left: 2rem;
    }
  }
}

Flexbox и CSS

.columnify {
  display: flex;
}

.columnify > * {
  flex: 1;
}

.columnify > *:not(:first-child) {
  margin-left: 2rem;
}
<div class="columnify">
  <div style="display: inline-block; height: 20px; background-color: blue;"></div>
  <div style="display: inline-block; height: 20px; background-color: blue"></div>
  <div style="display: inline-block; height: 20px; background-color: blue"></div>
</div>

Ответ 19

Я нахожу, что самый простой способ сделать это - с процентами и просто позволять разметке увеличить свою ширину

Это означает, что вы получите что-то вроде этого, если вы используете ваш пример

#box {
   display: flex;
}

.item {
   flex: 1 1 23%;
   margin: 0 1%;
}

Значит, ваши значения основаны на ширине, хотя это может быть нехорошо для всех.

Ответ 20

#box {
  display: flex;
  width: 100px;
}
.item {
  background: gray;
  width: 50px;
  height: 50px;
}
/* u mean utility */
.u-gap-10 > *:not(:last-child) {
  margin-right: 10px;
}
<div id='box' class="u-gap-10">
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
</div>

Ответ 21

Здесь сетка элементов интерфейса карты с интервалом, заполненным с помощью гибкой коробки:

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

Я был расстроен с помощью ручного распределения карт, манипулируя отступом и полями с результатами iffy. Итак, вот комбинации атрибутов CSS, которые я нашел очень эффективными:

.card-container {
  width: 100%;
  height: 900px;
  overflow-y: scroll;
  max-width: inherit;
  background-color: #ffffff;
  
  /*Here the relevant flexbox stuff*/
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: flex-start;
  flex-wrap: wrap; 
}

/*Supplementary styles for .card element*/
.card {
  width: 120px;
  height: 120px;
  background-color: #ffeb3b;
  border-radius: 3px;
  margin: 20px 10px 20px 10px;
}
<section class="card-container">
        <div class="card">

        </div>
        <div class="card">

        </div>
        <div class="card">

        </div>
        <div class="card">

        </div>
      </section>

Ответ 22

Просто используйте .item +.item в селекторе для совпадения со вторым .item

#box {
  display: inline-flex;
  margin: 0 -5px;
}
.item {
  background: gray;
  width: 10px;
  height: 50px;
}

#box .item + .item {
  margin-left: 10px;
}
<div id='box'>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
</div>

Ответ 23

Предполагая, что:

  • Вы хотите, чтобы 4-х столбчатая сетка с обертыванием
  • Количество элементов не обязательно кратно 4

Установите левое поле для каждого элемента, кроме 1-го, 5-го, 9-го предметов и так далее; и установите фиксированную ширину для каждого элемента. Если левое поле составляет 10px, то каждая строка будет иметь 30px margin между 4 элементами, процентная ширина элемента может быть рассчитана следующим образом:

100% / 4 - horizontal-border - horizontal-padding - left-margin * (4 - 1) / 4

Это достойное решение для проблем, связанных с последним рядом flexbox.

.flex {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  margin: 1em 0;
  background-color: peachpuff;
}

.item {
  margin-left: 10px;
  border: 1px solid;
  padding: 10px;
  width: calc(100% / 4 - 2px - 20px - 10px * (4 - 1) / 4);
  background-color: papayawhip;
}

.item:nth-child(4n + 1) {
  margin-left: 0;
}

.item:nth-child(n + 5) {
  margin-top: 10px;
}
<div class="flex">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
  <div class="item">4</div>
</div>
<div class="flex">
  <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>
<div class="flex">
  <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 class="item">9</div>
</div>

Ответ 24

Существует действительно хороший, аккуратный, способ только для CSS, чтобы сделать это (что можно считать "лучше").

Из всех ответов, представленных здесь, я нашел только тот, который использует calc() успешно (Дариуш Сикорский). Но когда поставлен с: "но он терпит неудачу, если в последней строке есть только 2 элемента", решение не было расширено.

Это решение решает вопрос ОП с альтернативой отрицательным полям и решает проблему, поставленную перед Дариушем.

заметки:

  • Этот пример демонстрирует только трехколоночный макет
  • Он использует calc() чтобы браузер делал математику так, как он хочет - 100%/3 (хотя 33.3333% тоже должен работать так же), и (1em/3)*2 (хотя.66em также должен хорошо работать).
  • Он использует ::after для заполнения последней строки, если элементов меньше, чем столбцов

.flex-container {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
}
.flex-container:after {
  content: "";
}
.flex-container > div,
.flex-container:after {
  box-sizing: border-box;
  width: calc((100%/3) - ((1em/3)*2));
}
.flex-container > :nth-child(n + 4) {
  margin-top: 1em;
}

/* the following is just to visualize the items */
.flex-container > div,
.flex-container:after {
  font-size: 2em;
}
.flex-container {
  margin-bottom:4em;
}
.flex-container > div {
  text-align: center;
  background-color: #aaa;
  padding: 1em;
}
.flex-container:after {
  border: 1px dashed red;
}
<h2>Example 1 (2 elements)</h2>
<div class="flex-container">
  <div>1</div>
  <div>2</div>
</div>

<h2>Example 2 (3 elements)</h2>
<div class="flex-container">
  <div>1</div>
  <div>2</div>
  <div>3</div>
</div>

Ответ 25

Свойство CSS gap:

Для flexbox есть новое свойство CSS, которое теперь работает в некоторых браузерах! (caniuse ссылка 1, ссылка 2).

#box {
  display: flex;
  width: 100px;
  background-color: red;
  gap: 10px;
}
.item {
  background: gray;
  width: 50px;
  height: 50px;
}
<div id='box'>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
</div>

Ответ 26

Он не будет работать в каждом случае, но если у вас есть гибкая ширина дочерних элементов (%) и известно количество элементов в строке, вы можете очень четко указать поля необходимых элементов с помощью nth-child селектора /s.

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

section {
  display: block
  width: 100vw;
}
.container {
  align-content: flex-start;
  align-items: stretch;
  background-color: #ccc;
  display: flex;
  flex-flow: row wrap;
  justify-content: flex-start;
  width: 100%;
}

.child-item {
  background-color: #c00;
  margin-bottom: 2%;
  min-height: 5em;
  width: 32%;
}

.child-item:nth-child(3n-1) {
  margin-left: 2%;
  margin-right: 2%;
}
<html>
  <body>
      <div class="container">
        <div class="child-item"></div>
        <div class="child-item"></div>
        <div class="child-item"></div>
        <div class="child-item"></div>
        <div class="child-item"></div>
        <div class="child-item"></div>
        <div class="child-item"></div>
      </div>
   </body>
</html>

Ответ 27

Я столкнулся с той же проблемой ранее, а затем наткнулся на ответ за это. Надеюсь, что это поможет другим людям в будущем.

длинный ответ короткий, добавьте границу к вашим дочерним элементам. то вы можете указать поля между гибкими элементами, как угодно. В фрагменте я использую черный для иллюстрации, вы можете использовать "прозрачный", если хотите.

#box {
  display: flex;
  width: 100px;
  /* margin: 0 -5px; *remove this*/
}
.item {
  background: gray;
  width: 50px;
  height: 50px;
  /* margin: 0 5px; *remove this*/
  border: 1px solid black; /* add this */
}
.item.special{ margin: 0 10px; }
<div id='box'>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item special'></div>
</div>

Ответ 28

Неверный трюк в полевом контейнере работает просто отлично. Вот еще один пример, который отлично работает с порядком, обертыванием, а что нет.

.container {
   border: 1px solid green;
   width: 200px;
   display: inline-block;
}

#box {
  display: flex;
  flex-wrap: wrap-reverse;
  margin: -10px;
  border: 1px solid red;
}
.item {
  flex: 1 1 auto;
  order: 1;
  background: gray;
  width: 50px;
  height: 50px;
  margin: 10px;
  border: 1px solid blue;
}
.first {
  order: 0;
}
<div class=container>
<div id='box'>
  <div class='item'>1</div>
  <div class='item'>2</div>
  <div class='item first'>3*</div>
  <div class='item'>4</div>
  <div class='item'>5</div>
</div>
</div>

Ответ 29

Я нашел хак, потому что мне это действительно нужно.

/* grid */
.container {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

.container::after, /* this makes sure odd element goes left and not space between */
.item {
  content:"";
  width: calc(33.3333% - 20px);
  margin-bottom: 40px;
}

/* extra styling - not important */
.item {
  height: 100px;
  background: #787878;
}
<div class="container">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

Ответ 30

Я устанавливал интервал на гибких элементах только в направлении, установленном их контейнером. Например, если контейнер гибкого контейнера установлен в поток слева направо (flex-direction:row), я установлю только правое поле на своих дочерних элементах, за исключением последнего:

.flex-lr{
    display:flex;
    flex-direction:row;
}

.flex-lr > *:not(:last-child){
    margin-right:5px;
}

Возможно, это работает на первый взгляд, но подождите! это не должно быть сделано, если для параметра justify-content установлено значение другое, которое start или end, поскольку все остальные значения уже распределяют пространство самостоятельно.

А что, если предметы обернутся? Затем мы должны добавить пространство к соответствующей стороне поперечной оси. Но как узнать, разрешает ли контейнер разрешать своим детям? А как насчет wrap-reverse?

Все эти соображения заставляли меня думать, что это не тривиальная задача, и для этого требуется небольшой шаг.

Мой подход основан на построении краткого набора классов, который действует как оболочка flexbox. Это имеет некоторые преимущества:

  1. Это позволяет "централизовать" все префиксы поставщиков в одной точке и забыть об этом.
  2. Он позволяет группировать свойства flexbox в один класс или даже переименовывать некоторую формулировку, используемую flexbox, что иногда может показаться не очень интуитивным (IMHO).
  3. Если я буду использовать эти классы, я смогу написать другие классы на основе значений свойств flex, на которые они опираются. Например, я мог бы установить интервал, основанный на направлении потока, выравнивании поперечной оси, обертывании и т.д.

Я закончил создание дизайнера flexbox, чтобы поиграть со всем этим, чтобы понять себя (и других), как работает flexbox, и понять, насколько замечателен flexbox. Plese не стесняйтесь использовать его по ссылке ниже:

http://algid.com/Flex-Designer

Итак, ниже вы найдете и отрисуйте классы, которые я использую, и значение расстояния (margin) для одного направления потока. Вы сможете сделать вывод о других или найти их в приведенной выше ссылке. Префиксы поставщиков были отброшены здесь для краткости.

/* Flex container definition */
.flex-lr{display:flex; flex-direction:row;}
.flex-tb{display:flex; flex-direction:column;}
.flex-rl{display:flex; flex-direction:row-reverse;}
.flex-bt{display:flex; flex-direction:column-reverse;}

/* Wrapping */
.wrap{flex-wrap:wrap;}
.nowrap{flex-wrap:nowrap;}
.wrap-rev{flex-wrap:wrap-reverse;}

/* Main axis alignment */
.align-start{justify-content:flex-start;}
.align-end{justify-content:flex-end;}
.align-center{justify-content:center;}
.align-between{justify-content:space-between;}
.align-around{justify-content:space-around;}
.align-evenly{justify-content:space-evenly;}

/* Cross axis alignment */
.cross-align-start{align-items:flex-start;}
.cross-align-end{align-items:flex-end;}
.cross-align-center{align-items:center;}
.cross-align-stretch{align-items:stretch;}
.cross-align-baseline{align-items:baseline;}

/* Cross axis alignment when content is wrapped */
.wrap-align-start{align-content:flex-start;}
.wrap-align-end{align-content:flex-end;}
.wrap-align-center{align-content:center;}
.wrap-align-stretch{align-content:stretch;}
.wrap-align-between{align-content:space-between;}
.wrap-align-around{align-content:space-around;}

/* Item alignment */
.item-cross-align-start{align-self:flex-start;}
.item-cross-align-end{align-self:flex-end;}
.item-cross-align-center{align-self:center;}
.item-cross-align-stretch{align-self:stretch;}
.item-cross-align-baseline{align-self:baseline;}
.item-cross-align-auto{align-self:auto;}

И вот то, что привело нас сюда: пространство между предметами:

/* Flow margin (left to right) */
.flex-lr.fm-0 > *:not(:last-child){margin-right:0;}
.flex-lr.fm-1 > *:not(:last-child){margin-right:3px;}
.flex-lr.fm-2 > *:not(:last-child){margin-right:7px;}
.flex-lr.fm-3 > *:not(:last-child){margin-right:15px;}
.flex-lr.fm-4 > *:not(:last-child){margin-right:32px;}

/* Cross axis */
.flex-lr.wrap.fm-0:not(.wrap-align-stretch):not(.wrap-align-between):not(.wrap-align-around) > *, .flex-lr.wrap.fm-0.wrap-align-stretch.cross-align-stretch > * {margin-bottom:0;}
.flex-lr.wrap.fm-1:not(.wrap-align-stretch):not(.wrap-align-between):not(.wrap-align-around) > *, .flex-lr.wrap.fm-1.wrap-align-stretch.cross-align-stretch > * {margin-bottom:3px;}
.flex-lr.wrap.fm-2:not(.wrap-align-stretch):not(.wrap-align-between):not(.wrap-align-around) > *, .flex-lr.wrap.fm-2.wrap-align-stretch.cross-align-stretch > * {margin-bottom:7px;}
.flex-lr.wrap.fm-3:not(.wrap-align-stretch):not(.wrap-align-between):not(.wrap-align-around) > *, .flex-lr.wrap.fm-3.wrap-align-stretch.cross-align-stretch > * {margin-bottom:15px;}
.flex-lr.wrap.fm-4:not(.wrap-align-stretch):not(.wrap-align-between):not(.wrap-align-around) > *, .flex-lr.wrap.fm-4.wrap-align-stretch.cross-align-stretch > * {margin-bottom:32px;}

/* wrap reverse */
.flex-lr.wrap-rev.fm-0:not(.wrap-align-stretch):not(.wrap-align-between):not(.wrap-align-around) > *, .flex-lr.wrap-rev.fm-0.wrap-align-stretch.cross-align-stretch > * {margin-top:0;}
.flex-lr.wrap-rev.fm-1:not(.wrap-align-stretch):not(.wrap-align-between):not(.wrap-align-around) > *, .flex-lr.wrap-rev.fm-1.wrap-align-stretch.cross-align-stretch > * {margin-top:3px;}
.flex-lr.wrap-rev.fm-2:not(.wrap-align-stretch):not(.wrap-align-between):not(.wrap-align-around) > *, .flex-lr.wrap-rev.fm-2.wrap-align-stretch.cross-align-stretch > * {margin-top:7px;}
.flex-lr.wrap-rev.fm-3:not(.wrap-align-stretch):not(.wrap-align-between):not(.wrap-align-around) > *, .flex-lr.wrap-rev.fm-3.wrap-align-stretch.cross-align-stretch > * {margin-top:15px;}
.flex-lr.wrap-rev.fm-4:not(.wrap-align-stretch):not(.wrap-align-between):not(.wrap-align-around) > *, .flex-lr.wrap-rev.fm-4.wrap-align-stretch.cross-align-stretch > * {margin-top:32px;}

Наконец, вот как будет выглядеть разметка:

<div class="flex-lr cross-align-center fm-3">
    <div>
        Some content here...
    </div>
    <div>
        A bit more stuff here...
    </div>
    <div class="flex-tb fm-3">
        <div>
            Now vertical content
        </div>
        <div>
            etc.
        </div>
    </div>
</div>

Это то, что я называю кодом вслух.