Кращий спосіб встановити відстань між елементами flexbox


777

Для того, щоб встановити мінімальну відстань між елементами 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>


28
Це не злом - це один із призначених методів вирівнювання предметів. Однак є й інші властивості. Дивіться w3.org/TR/css3-flexbox/#alignment
— BoltClock

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

Зважаючи на це, це запаси поля в flexbox. Інше питання має право швидше [Як я можу зупинити останній запас краху у flexbox? ] ( stackoverflow.com/questions/38993170/… )
— Джек Ян

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

2
@JohnCarrell firefox фактично вже підтримує gapвласність на гнучких контейнерах ( caniuse )
— Danield

Відповіді:


427
  • Flexbox не має поля руйнування.
  • Flexbox не має нічого подібного до border-spacingтаблиць (за винятком властивості CSS, gapяка не підтримується в більшості браузерів, каніусів )

Тому досягти того, про що ви просите, трохи складніше.

На мій досвід, "найчистіший" спосіб, який не використовує :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>


219
Це не виконує те саме, що задається запитанням, у вас буде крайній лівий і правий відступ 10 пікселів, який я припускаю, що вони не мають наміру. Звідси негативні межі в оригінальному питанні.
— Кріс Нікола

17
Що робити, якщо orderвластивість встановлено? :first-child/:last-childне працюватиме, як очікувалося.
— Гурія

4
"Flexbox не має поля руйнування". Дуже проникливий і, мабуть, правдивий, але чи можу я попросити цитати?
— chharvey

2
Це не гірша відповідь, ніж оригінальне запитання? Цей метод вимагає, щоб у вас було місця навколо контейнера, а жолоби повинні бути завжди парними.
— безмежний

7
@chharvey, зі специфікації w3.org/TR/css-flexbox-1/#item-margins , "Поля суміжних елементів флексу не руйнується".
— romellem

195

Це не злом. Цю ж техніку застосовують і завантажувальний засіб та його сітка, хоча замість поля, завантажувальний пристрій використовує набивання для своїх cols.

.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 calc з підтримкою декількох рядків

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

Демо Fiddle

   
.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;флексбокс. Модель 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
чудова відповідь. поля флексбоксу використовуються по-різному (люблять поглинати зайвий простір), тому прозорі рамки забезпечують відмінне рішення для рівномірно розташованих елементів, які можуть обернутись подібною поведінкою
— Eolis

4
за винятком випадків, коли ви використовуєте колір тла, ваш фон перевищує бажані рамки.
— ahnbizcad

2
@ahnbizcad Добре з різними кольорами фону ви можете використовувати білий або адекватний колір залежно від способу тла.
— hexalys

27
@ahnbizcad: Якщо вам не потрібна підтримка IE8, це краще рішення:background-clip: padding-box
— Альбін,

5
Коментар Альбіна тут потребує більше голосів! Це найкраще рішення. Прозорі межі в поєднанні з фоном-кліпом: набивна коробка (і негативні поля на контейнері, якщо це потрібно для правильного вирівнювання країв) - ідеальне рішення. IE8 так чи інакше не підтримує flexbox, тому його відсутність підтримки для фонового кліпу не має значення.
— Брайан

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>

Нижня сторона цього методу в програмі Mobile 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то воно розділить діл на 4fractionsспробу і заповнить дочірні елементи в кожному fractions, наскільки мені відомо, це єдиний спосіб grid. Що я сказав у відповіді, це те, що якщо користувачеві потрібно розділити діл на 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 { 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
Чистий розчин. Працює для будь-якої кількості легких дочірніх елементів.
— Konrad Gałęzowski

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>

Якщо ви хочете дозволити гнучку обгортання , дивіться наступний приклад.

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 Я додав підхід до роботи з гнучким обгортанням, див. Другу частину вище.
— Наклейки

Найкраща відповідь для мене ... просто, чисто, ефективно! Відмінно
— справлявся

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
Хіба це по суті не є таким, як приклад, наведений у питанні?
— форд

10

За даними #ChromDevSummit , є реалізація gapвластивості для Flexbox, хоча на даний момент (14 листопада 2019 року) вона підтримується лише у Firefox, але незабаром має бути впроваджена в Chrome:

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

Демонстраційна демонстрація

Я оновлю свою відповідь, як тільки вона надійде до Chrome.


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
Це все ще додає жолоб перед першим і після останнього пункту, що ОП запобігає використанню негативних запасів.
— герман

2
Flexbox не підтримує calc () всередині елемента "flex" в IE 11.
— Adam Šipický

Не можна завжди використовувати. уявіть, чи є також необхідний кордон для прямих дітей
— Андріс

9

Гнучкий контейнер з -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;
}

3
Вибачте, я цього не зрозумів. Що нового означає ваша відповідь, що не сказано безпосередньо у запитанні?
— користувач

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

ось приклад кодексу, що показує цей ефект. codepen.io/dalgard/pen/Dbnus
— педальпета

8

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


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

6

gapВластивість CSS :

Існує нове gapвластивість CSS для макетів з декількома стовпцями, флекси та сітки, яке працює в деяких браузерах зараз! (Див. Чи можна використовувати посилання 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

За допомогою флексотерапії створення жолобів - це біль, особливо коли йде обгортання.

Вам потрібно використовувати від'ємну маржу ( як показано в запитанні ):

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

Для використання всіх елементів, крім першого a, використовується сусідній селектор . Завдяки flexbox, це навіть призводить до отримання однаково широких елементів. Це також можна зробити з вертикально розташованими елементами і , звичайно..itemmargin-leftmargin-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>

Ця ж методика може бути використана для звичайних гнучких рядків і стовпців на додаток до вкладеного вище прикладу та розширена класами для інтервалів, відмінних від 4 пікселів.


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 ).
— rishat

2

Ось сітка елементів інтерфейсу картки з проміжком, виконаним за допомогою гнучкої коробки:

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

Мене розчарувало розставлення карт вручну, маніпулюючи прокладками та полями з результатами iffy. Тож ось комбінації атрибутів 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-го пункту тощо; і встановити фіксовану ширину для кожного елемента. Якщо лівий запас дорівнює 10 пікселів, то в кожному рядку буде розміщено 30 пікселів поля між 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 () (автор Даріуш Сікорський). Але коли поставлено: "але це не вдається, якщо в останньому ряду є лише 2 пункти", рішення не було розширено.

Це рішення вирішує питання ОП з альтернативою негативним надбавкам та вирішує проблему, поставлену перед Даріушем.

примітки:

  • Цей приклад демонструє лише макет з 3 стовпцями
  • Він використовує calc()для того, щоб браузер 100%/3 виводив математику так, як йому хочеться (хоча 33,3333% має працювати так само добре) , і (1em/3)*2 (хоча .66 також повинен добре працювати) .
  • Він використовує ::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 до того, що вам подобається. У фрагменті я використовую чорний колір для ілюстрації, ви можете використовувати "прозорий", якщо хочете.

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