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

476

Чтобы установить минимальное расстояние между элементами 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>
  • 14
    Это не хак - это один из предполагаемых методов выравнивания предметов. Есть и другие свойства, хотя. См. W3.org/TR/css3-flexbox/#alignment
  • 4
    Да, я понимаю. Но, например, есть свойство column-gap, которое дает нам возможность контролировать расстояние от контейнера: w3.org/TR/css3-multicol/#column-gap
Показать ещё 8 комментариев
Теги:
flexbox

34 ответа

248
Лучший ответ
  • У Flexbox нет сворачиваемых полей.
  • Flexbox не имеет ничего похожего на border-spacing таблицами.

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

По моему опыту, "самый чистый" способ, который не использует :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>
  • 127
    Это не то же самое, что задает вопрос, у вас будет отступ в 10 пикселей слева и справа, что, я полагаю, они не собираются иметь. Отсюда и отрицательные поля в исходном вопросе.
  • 13
    Как насчет order установить свойство order ? :first-child/:last-child не будет работать должным образом.
Показать ещё 5 комментариев
164

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

.row {
  margin:0 -15px;
}
.col-xx-xx {
  padding:0 15px;
}
  • 1
    Единственная проблема с этим методом - поддерживать элементы одинаковой высоты с фоновыми цветами. Абсолютное позиционирование с height:100%; width:100% игнорирует заполнение элемента.
  • 3
    Проблема здесь в IE10 и 11. Значения flex-basis based не учитывают box-sizing: border-box , поэтому дочерний элемент с любым отступом или границей будет переполнять родительский (или перенос в этом случае). Источник
Показать ещё 3 комментария
77

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

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

например.

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

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

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

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

  • 5
    отличный ответ. поля во флексбоксе используются по-разному (например, для поглощения дополнительного пространства), поэтому прозрачные границы обеспечивают отличное решение для равномерно расположенных элементов, которые могут переноситься с использованием полей.
  • 4
    за исключением случаев, когда вы используете цвет фона, ваш фон превышает желаемые границы.
Показать ещё 4 комментария
69

flexbox и css calc()

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

Демо-версия скрипта

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

.flexbox > div {
  /*
    1/3  - 3 columns per row
    10px - spacing between columns 
  */
  box-sizing: border-box;
  margin-bottom: 10px;
  width: calc(1/3*100% - (1 - 1/3)*10px);
}
<div class="flexbox">
  <div>col</div>
  <div>col</div>
  <div>col</div>
  <div>col</div>
  <div>col</div>
  <div>col</div>
</div>
  • 3
    Я люблю это математическое решение. Я бы предпочел использовать flex-basis: calc( (100% + $gutter)/$cols - $gutter ); :-)
  • 8
    Мне нравится это решение, но оно терпит неудачу, если в последнем ряду только 2 элемента. Элементы не складываются вместе из-за justify-content .
Показать ещё 2 комментария
35

ОБНОВЛЕНО 2019 ↓

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

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

СТАРЫЙ ОТВЕТ ↓

Если вы хотите, вы всегда можете использовать комбинацию CSS:

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

Приведенный выше код поможет. В этом методе нет необходимости margin: 0 -5px; в оболочку #box.

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

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

Надеюсь, это было полезно.

  • 2
    Хорошее решение, но оно не работает с элементами, которые переносятся - они все еще считаются братьями и сестрами и получат левое поле.
  • 0
    @ Я не понимаю, можете ли вы быть более конкретным, если вы дадите мне пример, я тоже смогу найти решение для этого!
Показать ещё 5 комментариев
17

Я нашел решение, основанное на селекторе css preceded by ~, и разрешает inifinite nesting.

Посмотрите на это перо для рабочего примера

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

.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>
  • 6
    ~ Является комбинатором General Sibling: он будет выбирать элементы в пределах одного и того же родителя. К сожалению, в CSS нет preceded by селектора. w3.org/wiki/CSS/Selectors/combinators/general
  • 0
    Это приводит к разным размерам предметов из-за того, что поля не применяются глобально.
Показать ещё 3 комментария
14

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

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>
  • 1
    Разве это не то же самое, что пример, приведенный в вопросе?
12

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

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

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

body {
  margin: 0;
}
.container {
  display: flex;
}
.item {
  flex: 1;
  background: gray;
  height: 50px;
  margin-right: 10px;
}
.item:last-child {
  margin-right: 0;
}
<div class="container">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>
  • 5
    Это не будет работать, если элементы обернуты, так как :last-child не влияет на каждый последний дочерний элемент в конце строки, правильно?
  • 0
    @Flimm Я добавил подход к работе с flex wrap, см. Вторую часть выше.
11

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

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

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

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

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

.flex-item {
  margin: 0 5px; // Alternatively: padding: 0 5px;
  flex: 1 0 auto;
}
  • 1
    Извини, я не понял. Что нового вводит ваш ответ, который не указан непосредственно в вопросе?
  • 0
    Во-первых, я хотел бы подытожить, что и маржа, и отступ для flex-элемента приводят к желаемому результату, потому что в существующих ответах упоминается только одно или другое. Во-вторых, я хотел бы привести пример, где пробелы сохраняются путем масштабирования самих flex-элементов.
Показать ещё 1 комментарий
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

  • 1
    Это все еще добавляет желоб до первого и после последнего элемента, что предотвращает использование отрицательных полей.
  • 2
    Flexbox не поддерживает calc () внутри элемента «flex» в IE 11.
6

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

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

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

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

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

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

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

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

#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

С помощью 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 Box, который предоставляет набор свойств выравнивания для использования во всех коробчатых моделях. Итак, теперь свойства:

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

Дополнительная информация:

3

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

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

2

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

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

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

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

заметки:

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

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

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

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

Также по адресу https://codepen.io/anon/pen/rqWagE

1

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

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

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

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

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

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

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

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

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

http://algid.com/Flex-Designer

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1

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

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

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

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

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

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

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

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

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

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

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

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

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

Здесь также добавляются столбчатая сетка с красивым слоем flex. Думаю, тебе понравится. Просмотреть Codepen

1

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

Изображение 4936

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

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

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

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

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

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

        </div>
      </section>

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

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

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

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

#box {
   display: flex;
}

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

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

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

Вы можете попробовать CSS3: не селектор

Например:

#box {
  display: flex;
  width: 100px;
  border: 1px red solid;
}

.item {
  background: gray;
  width: 10px;
  height: 100px;
  flex: 1 1 auto;
}

.item:not(:last-child) {
  margin-right: 5px;
}
<div id='box'>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></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>
0

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

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

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

#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

Я разместил свой подход flexbox здесь:

Одна идея, которую я отклонил, заключалась в том, чтобы удалить прописку из внешних столбцов примерно так:

div:nth-child(#{$col-number}n+1) { padding-left: 0; }
div:nth-child(#{$col-number}n+#{$col-number}) { padding-left: 0; }

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

https://jsfiddle.net/x3jvfrg1/

0

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

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

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

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

.child-item:nth-child(3n-1) {
  margin-left: 2%;
  margin-right: 2%;
}
<html>
  <body>
      <div class="container">
        <div class="child-item"></div>
        <div class="child-item"></div>
        <div class="child-item"></div>
        <div class="child-item"></div>
        <div class="child-item"></div>
        <div class="child-item"></div>
        <div class="child-item"></div>
      </div>
   </body>
</html>
  • 0
    Не отзывчивый Работает только для фиксированной ширины родителя.
  • 1
    ОП не требует адаптивного решения, и в их примере используется фиксированная ширина. Учитывая, что здесь используются значения%, легко утверждать, что это отзывчиво, поскольку элементы будут адаптироваться к размеру родительского элемента, который устанавливается в процентах.
-1

 :root{
  --inner: 20px;
  --gap: 10px; /* same as gutter */
  
  /* flex-flow in row 
  ---------------------*/
  --row-wrap: row wrap;
  --row-nowrap: row nowrap;
  
  /* flex-flow in col 
  ---------------------*/
  --col-wrap: column wrap;
  }
  
  .row {
  display: flex;
  flex-direction: var(--flex-row);
}
/* additional wrapping classes (if needed)
-------------------------------------------*/
.nowrap {
  display: flex;
  flex-flow: var(--row-nowrap);
}
.wrap {
  display: flex;
  flex-flow: var(--col-wrap);
}
/*----------------------------------------*/
[class*="col-"] {
  border: 1px solid #ccc;
  margin: var(--gap);
  padding: var(--inner);
  height: auto;
  background: #333;
  flex: 1 0 auto;
}
.col-3 {
  flex: 3;
}
<div class="row">
  <div class='col-3'></div>
  <div class='col-3'></div>
  <div class='col-3'></div>
  <div class='col-3'></div>
</div>

Также вы можете посмотреть этот пример.

-1

ТЛ; др

$gutter: 8px;

.container {
  display: flex;
  justify-content: space-between;

  .children {
    flex: 0 0 calc(33.3333% - $gutter);
  }
}
  • 4
    Пожалуйста, расширьте свой ответ объяснением.
-2

Что ж, самое простое решение относительно вашего CSS, imo, - это добавить разделители в HTML:

<div id='box'>
  <div class='item'></div>
  <div style='width: 5px;'></div>
  <div class='item'></div>
  <div class='item'></div>
  <div class='item'></div>
</div>

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

вот пример

  • 0
    Основной вопрос касался техники Flexbox, а ваш ответ не отвечает «в теме». Также ваше решение очень старое (даже если оно выполняет свою работу).
  • 0
    Вы не понимаете примитивов. они всегда будут, независимо от того, шумиха. У flexbox есть свое определение, и если оно не говорит о точном интервале - нет никакого интервала. Кроме того, эти элементы, показанные автором, являются пустыми полосами (рассматривайте их как видимые разделители) - если бы там был контент, он мог бы быть разнесен внутри с помощью отступов оболочки.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню