Кращий спосіб встановити відстань між елементами 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.