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


781

Чтобы установить минимальное расстояние между элементами 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>


29
Это не хак - это один из предполагаемых методов выравнивания предметов. Есть и другие свойства, хотя. См. W3.org/TR/css3-flexbox/#alignment
BoltClock

4
Да, я понимаю. Но, например, есть свойство столбца-пробела, которое дает нам возможность контролировать расстояние от контейнера: w3.org/TR/css3-multicol/#column-gap
Саша Косс

Конечно, это гибкие поля во флексбоксе. Другой вопрос имеет право на [Как я могу остановить последний крах в флексбоксе? ] ( stackoverflow.com/questions/38993170/… )
Джек Ян

6
CSS Box Выравнивание Модуль Level 3 включает в себя раздел о зазорах между коробками - который относится к элементам с несколькими столбцами, гибких контейнеров и контейнеров сетки. Так что в конце концов это будет просто, как: row-gap: 5px- сделано.
Данилд

2
@JohnCarrell firefox на самом деле уже поддерживает gapсвойство в flex-контейнерах ( caniuse )
Данилд

Ответы:


428
  • 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>


220
Это не то же самое, что задает вопрос, у вас будет отступ в 10 пикселей слева и справа, который, как я предполагаю, они не собираются иметь. Отсюда и отрицательные поля в исходном вопросе.
Крис Никола

17
А как насчет, если orderсвойство установлено? :first-child/:last-childне будет работать, как ожидалось.
Гурия

4
«У Flexbox нет складывающихся полей». Очень проницательно и, по-видимому, правда, но могу ли я попросить процитировать?
Чарви

2
Разве это не худший ответ, чем оригинальный вопрос? Этот метод требует, чтобы у вас было пространство вокруг контейнера, а желоб всегда должен быть четным числом.
limitlessloop

7
@chharvey, из спецификации w3.org/TR/css-flexbox-1/#item-margins : «Поля смежных гибких элементов не разрушаются».
romellem

197

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

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

1
Единственная проблема с этим методом - поддерживать элементы одинаковой высоты с фоновыми цветами. Абсолютное позиционирование с height:100%; width:100%игнорированием заполнения элемента.
Стивен Вачон

3
Проблема здесь заключается в том, что значения IE10 и 11. flex-basisне учитываются box-sizing: border-box, поэтому дочерний элемент с любым отступом или рамкой будет переполнять родительский (или перенос в этом случае). Источник
Карсон

18
У этого подхода есть еще одна проблема: подобная настройка поля может увеличить ширину страницы. Демонстрация: jsfiddle.net/a97tatf6/1
Натан Осман

4
Хотя я согласен, что это не хак, тот факт, что что-то широко используется, не означает, что это не хак. См. Полифиллы, временные исправления безопасности, редактирование гексов и т. Д.
Уильям,

15
Конечно это взломать. Поскольку Bootstrap использует этот метод, это не значит, что он не хакерский. Это просто означает, что Bootstrap использует хак.
Майкл Бенджамин

108

Flexbox и CSS калькулятор с поддержкой нескольких строк

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

Скрипка Демо

   
.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: 10px 10px 0 0;
  outline: 1px dotted red;
  width: calc(1/3*100% - (1 - 1/3)*10px);
}

/*
  align last row columns to the left
  3n - 3 columns per row
*/
.flexbox > div:nth-child(3n) {
  margin-right: 0;
}

.flexbox::after {
  content: '';
  flex: auto;
}

/*
  remove top margin from first row
  -n+3 - 3 columns per row 
*/
.flexbox > div:nth-child(-n+3) {
  margin-top: 0;
}
<div class="flexbox">
  <div>col</div>
  <div>col</div>
  <div>col</div>
  <div>col</div>
  <div>col</div>
</div>

Обратите внимание, этот код может быть короче с помощью SASS

Обновление 2020.II.11 Выровненные столбцы в последнем ряду слева

Обновление 2020.II.14 Удалено маржинальное дно в последнем ряду


13
Мне нравится это решение, но оно терпит неудачу, если в последнем ряду только 2 элемента. Элементы не складываются вместе из-за justify-content.
Джеймс Брантли,

4
чтобы исправить проблему с двумя пунктами, просто измените на justify-content: space-evenly;или justify-content: space-around;.
Пол Руни

6
@PaulRooney На сайте с несколькими списками вы можете не всегда знать количество элементов, если списки создаются CMS.
NinjaFart

1
@ 1.21gigawatts Пожалуйста, не вносите произвольные изменения в чужой код / ​​ответ; вместо этого напишите свой собственный ответ.
TylerH

2
@TylerH Это не было произвольным. Вопрос задан как "... установить расстояние между элементами flexbox". Этот ответ не показывает размер желоба. Установка цвета фона показывает желоб. Добавление границы показывает, что под последним рядом есть поле.
1.21 гигаватт

93

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

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

например

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

Также обратите внимание, что вам нужно min-width: 50px;для flexbox. Гибкая модель не будет обрабатывать фиксированные размеры, если вы не 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
отличный ответ. поля во флексбоксе используются по-разному (например, для поглощения дополнительного пространства), поэтому прозрачные границы обеспечивают отличное решение для равномерно распределенных элементов, которые можно переносить с помощью полей, как в случае с
полями

4
кроме случаев, когда вы используете цвет фона, ваш фон превышает желаемые границы.
Ahnbizcad

2
@ahnbizcad Хорошо с различными цветами фона, вы можете использовать белый или адекватный цвет в зависимости от того, какой фон является фоном.
гексалис

27
@ahnbizcad: Если вам не нужна поддержка IE8, это лучшее решение:background-clip: padding-box
Альбин

5
Комментарий Альбина здесь нуждается в большем количестве голосов! Это лучшее решение. Прозрачные границы в сочетании с background-clip: padding-box (и отрицательные поля на контейнере, если необходимо, для правильного выравнивания краев) является идеальным решением. IE8 в любом случае не поддерживает flexbox, поэтому отсутствие поддержки background-clip не должно иметь значения.
Брайан

74

Это решение будет работать для всех случаев, даже если есть несколько строк или любое количество элементов. Но количество разделов должно быть таким же, как вы хотите, чтобы 4 в первом ряду и 3 во втором ряду, это не сработает, поэтому пространство для 4-го содержимого будет пустым, а контейнер не заполнится.

Мы используем 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>

Недостаток этого метода в мобильном Opera Mini не будет поддерживаться, а в ПК это работает только после IE10 .

Примечание для полной совместимости браузера, включая IE11, пожалуйста, используйте Autoprefixer


СТАРЫЙ ОТВЕТ

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

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

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

Код ниже сделает свое дело. В этом методе нет необходимости давать margin: 0 -5px;в#box обертку.

Рабочий образец для вас:

#box {
  display: flex;
  width: 100px;
}
.item {
  background: gray;
  width: 22px;
  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>


Я отредактировал ваш основанный на сетке ответ, чтобы продемонстрировать, что он работает правильно, даже если в последней строке меньше элементов. Чтобы доказать это работает в этом случае. (Вы можете вернуться , если вам не нравится это изменение.)
ToolmakerSteve

В соответствии с этим вопросом они только попросили правильно заполнить пространство дочерними элементами без взлома, что то, что я сделал, используя сетку, мы можем управлять согласно определению, которое grid-template-columnsмы определяем не динамически. Поэтому, если вы дадите значение, 1fr 1fr 1fr 1frто он разделит div на 4fractionsи попытается заполнить дочерние элементы в каждом fractions, насколько я знаю, это единственный выход grid. В ответе я сказал, что если пользователю нужно разделить div на 4 и использовать их со многими элементами даже для нескольких строк, это gidпоможет.
WeBBer

69

Вы можете использовать & > * + *в качестве селектора для эмуляции 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>

Если вам нужно поддерживать flex-упаковку , вы можете использовать элемент-оболочку:

.flex { display: flex; flex-wrap: wrap;  }
.box { background: gray; height: 100px; min-width: 100px; flex: auto; }
.flex-wrapper {outline: 1px solid red; }

/* ----- Flex gap 10px: ----- */

.flex > * {
  margin: 5px;
}
.flex {
  margin: -5px;
}
.flex-wrapper {
  width: 400px; /* optional */
  overflow: hidden; /* optional */
}
<div class='flex-wrapper'>
  <div class='flex'>
    <div class='box'></div>
    <div class='box'></div>
    <div class='box'></div>
    <div class='box'></div>
    <div class='box'></div>
  </div>
</div>


3
Чистый раствор. Работает для любого количества гибких дочерних элементов.
Конрад Галеновский

1
Это было то, что я искал и отлично работал для меня 👍
Пол Одеон

Однако следует отметить, что *оператор не увеличивает специфичность, как вы могли ожидать. Таким образом, в зависимости от вашей текущей CSS, вам может понадобиться либо увеличить специфичность для .flex > *селектора, либо добавить !importantк правилу, если есть другие селекторы, применяющие маржу к этому элементу.
Пол Одеон

Лучшее решение 👍
o01

26

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

Вы также можете использовать общий селектор братьев ~или +сестер, чтобы установить левое поле для элементов, исключая первый .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>

Если вы хотите разрешить Flex Wrap , см. Следующий пример.

body {
  margin: 0;
}

.container {
  display: flex;
  flex-wrap: wrap;
  margin-left: -10px;
}

.item {
  flex: 0 0 calc(50% - 10px);
  background: gray;
  height: 50px;
  margin: 0 0 10px 10px;
}
<div class="container">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>


6
Это не будет работать, если элементы обернуты, так :last-childкак не влияет на каждый последний дочерний элемент в конце строки, правильно?
Flimm

2
@Flimm Я добавил подход к работе с flex wrap, см. Вторую часть выше.
Наклейки

Лучший ответ для меня ... простой, чистый, эффективный! Отлично
сработал

16

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

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

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

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


Это приводит к разным размерам предметов из-за того, что поля не применяются глобально.
Стивен Вачон

Вам также понадобится добавить дополнительный CSS для обработки небольших экранов, поскольку на мобильных устройствах это выглядит немного странно, я бы применил правило .box ~ .box к большим экранам, а для небольших экранов установил класс .box с максимальной шириной. 100% и дно наценки.
rhysclay

14

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

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>

2
Разве это не то же самое, что пример, приведенный в вопросе?
Форд


9

Я использовал это для обернутых и фиксированных столбцов ширины. Ключ здесь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


2
Это все еще добавляет желоб до первого и после последнего элемента, что предотвращает использование отрицательных полей.
herman

2
Flexbox не поддерживает calc () внутри элемента «flex» в IE 11.
Адам Шипицкий,

Не могу быть всегда использован. представьте, есть ли граница, необходимая для прямых детей
Андрис

9

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

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

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

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

3
Извини, я не понял. Что нового вводит ваш ответ, который не указан непосредственно в вопросе?
пользователь

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

Вот пример кода, показывающий этот эффект. codepen.io/dalgard/pen/Dbnus
педальпет

8

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


Обсуждение здесь: github.com/w3c/csswg-drafts/issues/1696 - они также упростят именование через CSS Grid, Flexbox и CSS Columns.
Фрэнк Ламмер

6

CSS gapсвойство:

Существует новое gapсвойство CSS для многостолбцовых, flexbox и сеточных макетов, которое теперь работает в некоторых браузерах! (См. Могу ли я использовать ссылку 1 ; ссылка 2 ).

#box {
  display: flex;
  flex-wrap: wrap;
  width: 200px;
  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>

На момент написания, это работает только в Firefox, к сожалению. В настоящее время он работает в Chrome, если вы включите «Включить экспериментальные функции веб-платформы» в about:flags.


5

Используя 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>


5

При использовании 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. Стоки: в row-gap, column-gapи gap свойства

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>

Больше информации:


4

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

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

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


8
Это будет работать до тех пор, пока гибкие элементы всегда находятся в одном ряду. Если обертывание разрешено, то, вероятно, этого будет недостаточно.
Ник Ф

4

Вот мое решение, которое не требует установки классов для дочерних элементов:

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


4

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

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


3

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

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

#box {
   display: flex;
}

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

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


Просто наткнулся на это решение и да, это очень приятно. По крайней мере, работает в моем случае (ручка для тех, кому это может показаться интересным: codepen.io/rishatmuhametshin/pen/XXjpaV ).
Ришат

2

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

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

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

.card-container {
  width: 100%;
  height: 900px;
  overflow-y: scroll;
  max-width: inherit;
  background-color: #ffffff;
  
  /*Here's 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>

Надеюсь, что это помогает людям, настоящее и будущее.


Обновление: этот интервал эффективен для мобильного рендеринга HTML-элементов, которые требуют определенного выравнивания (например, по центру, слева и т. Д.). Если вы обнаружите, что используете flex box для мобильной разработки, я обнаружил облегчение при переходе к выравниванию, основанному исключительно на марже.
buildpax

2

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>

Играть с ним на JSFiddle .


1

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


1

Просто используйте .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>


1

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

  • Вы хотите 4 столбца сетки с оберткой
  • Количество предметов не обязательно кратно 4

Установите левое поле для каждого элемента, кроме 1-го, 5-го, 9-го элемента и т. Д .; и установить фиксированную ширину для каждого элемента. Если левое поле равно 10px, то каждая строка будет иметь отступ 30px между 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>


1

Есть действительно хороший, аккуратный, CSS-единственный способ сделать это (который можно считать «лучше»).

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

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

ноты:

  • Этот пример демонстрирует только макет с 3 столбцами
  • Он 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>

Также на https://codepen.io/anon/pen/rqWagE


1

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

CSS-макет сетки имеет разрыв (ранее сетка-разрыв) в течение некоторого времени. Указывая внутренний интервал вмещающего элемента, а не интервал вокруг дочерних элементов, разрыв решает многие распространенные проблемы компоновки. Например, с пробелом вам не нужно беспокоиться о полях дочерних элементов, вызывающих нежелательные пробелы по краям содержащего элемента:

К сожалению, сейчас только FireFox поддерживает разрыв в гибких макетах.

@use postcss-preset-env {
  stage: 0;
  browsers: last 2 versions
}

section {
  width: 30vw;
  
  display: grid;
  gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(12ch, 1fr));
  
  &[flex] {
    display: flex;
    flex-wrap: wrap;
  }
  
  margin-bottom: 3rem;
}

.tag {
  color: white;
  background: hsl(265 100% 47%);
  padding: .5rem 1rem;
  border-radius: 1rem;
}

button {
  display: inline-flex;
  place-items: center;
  gap: .5rem;
  background: hsl(265 100% 47%);
  border: 1px solid hsl(265 100% 67%);
  color: white;
  padding: 1rem 2rem;
  border-radius: 1rem;
  font-size: 1.25rem;
}

body {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}
<section>
  <h1>Grid</h1> 
  <div class="tag">Awesome</div>
  <div class="tag">Coo</div>
  <div class="tag">Rad</div>
  <div class="tag">Math</div>
</section>
<br>
<section flex>
  <h1>Flex</h1>
  <div class="tag">Awesome</div>
  <div class="tag">Coo</div>
  <div class="tag">Rad</div>
  <div class="tag">Math</div>
</section>


gapбыло уже рекомендовано в ответе здесь stackoverflow.com/a/58041749/2756409 Кроме того, это не CSS.
TylerH

0

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

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

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>


Не отзывчивый Работает только для фиксированной ширины родителя.
Зеленый

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

0

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

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

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


0

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

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

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