Flex-box: выровнять последний ряд по сетке


380

У меня есть простая схема flex-box с контейнером, как:

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

Теперь я хочу, чтобы элементы в последнем ряду были выровнены с другим. justify-content: space-between;следует использовать, потому что ширина и высота сетки могут быть скорректированы.

В настоящее время это выглядит как

Элемент в правом нижнем углу должен быть посередине

Здесь я хочу, чтобы элемент в правом нижнем углу находился в «средней колонке». Какой самый простой способ сделать это? Вот небольшой jsfiddle, который показывает это поведение.

.exposegrid {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

.exposetab {
  width: 100px;
  height: 66px;
  background-color: rgba(255, 255, 255, 0.2);
  border: 1px solid rgba(0, 0, 0, 0.4);
  border-radius: 5px;
  box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
  margin-bottom: 10px;
}
<div class="exposegrid">
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
</div>



Проверьте мое решение здесь, я думаю, что оно хорошо работает без взлома, только математика: stackoverflow.com/questions/18744164/…
Себастьен Лорбер,

5
В качестве альтернативы, use может использовать более новый модуль CSS-сетки - у которого нет этой проблемы
Danield


1
Я добавил универсальное JS-решение для случаев, когда ширина дочернего элемента является переменной, и количество элементов в строке также является переменным.
дао

Ответы:


417

Добавить, ::afterкоторый автоматически заполняет пространство. Не нужно загрязнять ваш HTML. Вот кодекс, показывающий это: http://codepen.io/DanAndreasson/pen/ZQXLXj

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

.grid::after {
  content: "";
  flex: auto;
}

17
Можно ли как-то заставить его работать с космическим окружением?
Том

61
@DanAndreasson Есть две проблемы: он не начинается слева (как пробел), а также расстояние между элементами последней строки отличается от предыдущего (моделирование некоторых элементов фиксированной ширины в «любом размере»). сетка - относится к обоим) ... codepen.io/anon/pen/gPoYZE Я хотел сохранить «стратегию» (пробел или пробел), но начать слева, как в предыдущих строках ... I Хотел узнать, можно ли обобщить ваше изумительное решение.
Том

44
Это работает только потому , что предметы дополняя их в пространство и объединенный процент ширина равны 100% для каждого набора 4. В этом codepen я удалил justify-content: space-between;из .gridи удалены , .grid:afterи он работает так же. Теперь, если вы попробовали что-то подобное, это полностью сломалось. Обратите внимание на ширину для каждого набора из 4 не добавить до 100%. В скрипте OP ширина задается в px, поэтому ваше решение не работает в этой ситуации.
Джейкоб Альварес

22
Изначально, пробуя это решение, предметы, в которых он был коротким в последнем ряду, не распределялись должным образом space-between. Однако, когда я установил flex-basisиз .grid:afterодной и тех же размеров , как и другие элементы в сетке (за-останова, перекрывая выше по умолчанию / базовый код модуля), последнее распространение строк правильно. Кажется, работает на Safari, iOS, Firefox, Chrome (нужно протестировать IE), и мой самый большой размер строки равен 3 в моей первоначальной реализации.
webbower

8
Для моих нужд это работало со следующей модификацией: { content: "";flex: 0 0 32%;max-width: 480px;}я изменил максимальную ширину с изменениями медиазапросов, чтобы сетка была идеальной при любой ширине.
Колин Уайзман

161

Одним из методов будет вставка нескольких дополнительных элементов (максимально возможное количество элементов в строке), которым присваивается нулевая высота. Пространство все еще разделено, но лишние ряды рушатся на нет:

http://codepen.io/dalgard/pen/Dbnus

body {
  padding: 5%;
}

div {
  overflow: hidden;
  background-color: yellow;
}

ul {
  display: flex;
  flex-wrap: wrap;
  margin: 0 -4px -4px 0;
  list-style: none;
  padding: 0;
}

li {
  flex: 1 0 200px;
  height: 200px;
  border-right: 4px solid black;
  border-bottom: 4px solid black;
  background-color: deeppink;
}
li:empty {
  height: 0;
  border: none;
}

*,
:before,
:after {
  box-sizing: border-box;
}
<div>
  <ul>
    <li>a</li>
    <li>b</li>
    <li>c</li>
    <li>d</li>
    <li>e</li>
    <li>f</li>
    <li>g</li>
    <li>h</li>
    <li>i</li>
    <li>j</li>
    <li>k</li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
  </ul>
</div>

В будущем это может стать достижимым за счет использования нескольких ::after(n).


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

33
Согласен, это грязно, но это работает, и менее взломано, чем много хаков. Черт возьми, я использую это, пока :: after (12) не получит поддержку, или пока они не добавят некоторые дополнительные параметры выравнивания. Это настоящий позор, так как то, как работает flexbox justify в данный момент, просто неправильно! Если бы вы оправдывали абзац текста, вы бы никогда не попытались оправдать последнюю строку. Определенно должен был быть вариант, я не могу поверить, что они пропустили это.
Codemonkey

4
Я придумал решение только для CSS. С учетом того, что он может учитывать только два отсутствующих элемента, поэтому он будет безопасно работать только в гибкой сетке, содержащей не более трех элементов на строку переноса. Демонстрация: codepen.io/lukejacksonn/pen/dozqVq Принцип здесь состоит в том, чтобы использовать псевдоэлементы в качестве дополнительных дочерних элементов и дать им то же свойство flex, что и у элементов в контейнере.
lukejacksonn

8
@ Кодемонки Иисус. Я только начал использовать flexbox, думая, как избавиться от всех этих хаков, предназначенных для выравнивания этих встроенных блоков внутри сетки, и теперь оказывается, что это просто невозможно! Я сразу же попал в этот блок, достигнув пределов, которые, как я думал, вряд ли когда-нибудь удастся достичь, решая все эти старые неразрешимые проблемы CSS. Не так быстро, наверное. Потребовалось всего 20 лет, чтобы получить правильное вертикальное центрирование - мы, конечно, можем подождать. Господи, это кажется такой простой задачей ...
Андрей

3
@ Далгард Я так не думаю. Смотрите мой комментарий .
Джейкоб Альварес

109

Как уже упоминалось в других постерах, не существует чистого способа выравнивания по левому краю последнего ряда с помощью flexbox (по крайней мере, согласно текущей спецификации).

Однако, для чего это стоит: с модулем CSS Grid Layout это удивительно легко создать:

В основном соответствующий код сводится к следующему:

ul {
  display: grid; /* 1 */
  grid-template-columns: repeat(auto-fill, 100px); /* 2 */
  grid-gap: 1rem; /* 3 */
  justify-content: space-between; /* 4 */
}

1) Сделать элемент контейнера контейнером сетки

2) Установите сетку с автоматическими столбцами шириной 100 пикселей. (Обратите внимание на использование автозаполнения (в отличие от auto-fit- который (для макета из одной строки) сворачивает пустые дорожки до 0), в результате чего элементы расширяются, чтобы занять оставшееся пространство. Это приведет к оправданному «пробелу между 'макет, когда сетка имеет только одну строку, что в нашем случае не то, что мы хотим. (посмотрите эту демонстрацию, чтобы увидеть разницу между ними)).

3) Установите промежутки / желоба для строк и столбцов сетки - здесь, так как нужно расположение «промежуток» - разрыв будет фактически минимальным, потому что он будет расти по мере необходимости.

4) Похоже на flexbox.

Codepen Demo ( измените размер, чтобы увидеть эффект)


4
Хорошее решение. Единственная проблема заключается в том, что он не работает с IE10 / 11.
Зенду

1
Что касается auto-fitошибки Chrome 57-60 (и браузеров, основанных на его движке, например, Samsung Internet 6.0), то была ошибка, потому что в то время спецификация была немного неоднозначной . Теперь спецификация была уточнена, и новые версии Chrome отображаются auto-fitправильно, но браузеры со старым движком все еще используются, поэтому, пожалуйста, будьте осторожны с этим значением.
Илья Стрельцын

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

2
@ Данилд, это предложение мне очень помогло, спасибо!
Крыс

4
Это должен быть принятый ответ. Я бы советовал использовать его с flexbox в качестве запасного варианта в духе прогрессивного улучшения: браузеры, которые не поддерживают сетку, будут отображать версию flexbox, которая достаточно близка для меня.
Палантир

27

Без какой-либо дополнительной разметки, просто добавление ::afterработало для меня, указав ширину столбца.

.grid {
  display:flex;
  justify-content:space-between;
  flex-wrap:wrap;
}
.grid::after{
  content: '';
  width: 10em // Same width of .grid__element
}
.grid__element{
  width:10em;
}

С HTML, как это:

<div class=grid">
   <div class="grid__element"></div>
   <div class="grid__element"></div>
   <div class="grid__element"></div>
</div>

9
это интересно, но не совсем правильно. проблема возникает, когда вы имеете дело с более чем двумя элементами в нижнем ряду - расстояние между элементами в верхних строках никогда не появляется в последнем; предметы плотно упакованы вместе, сводя на нет оригинальную полезность пространства между ними.
Джон Хаугеланд

даже лучше, если вы используете flex-basis: 10emвместо ширины.
Бейтаровски

14

Ты не можешь Flexbox не является сеточной системой. Он не имеет языковых конструкций, чтобы делать то, что вы просите, по крайней мере, если вы используете justify-content: space-between. Самое близкое, что вы можете получить с Flexbox, это использовать ориентацию столбца, которая требует установки явной высоты:

http://cssdeck.com/labs/pvsn6t4z (примечание: префиксы не включены)

ul {
  display: flex;
  flex-flow: column wrap;
  align-content: space-between;
  height: 4em;
}

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

http://cssdeck.com/labs/dwq3x6vr (примечание: префиксы не включены)

ul {
  columns: 15em;
}

2
Есть выход; смотри мой ответ.
Далгард

@ dalgard, твой ответ - обходной путь, а не верное решение. ответ кимманон правильный.
Иона

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

2
@dalgard Это не меняет того факта, что Flexbox не предоставляет языковые конструкции для выполнения того, что запрашивают. Кроме того, я бы сказал, что добавление поддельных элементов - это очень грязная практика, прямо здесь с использованием таблиц для разметки.
Цимманон

4
Это не красиво, но разработка интерфейса - это искусство возможного; Прагматизм является основной предпосылкой. Я думаю, что слово чрезвычайно неуместно, так как дополнительные элементы используются для стилизации на 99,9% реальных веб-сайтов (см. Элементы контейнера Bootstrap).
Далгард

12

Возможное решение - использовать justify-content: flex-start;для .gridконтейнера ограничения по размеру для его дочерних элементов и поля для соответствующих дочерних элементов - в зависимости от желаемого количества столбцов.

Для сетки из 3 столбцов базовый CSS будет выглядеть так:

.grid {
    display: flex;
    flex-flow: row wrap;
    justify-content: flex-start;
}

.grid > * {
    flex: 0 0 32%;
    margin: 1% 0;
}

.grid > :nth-child(3n-1) {
    margin-left: 2%;
    margin-right: 2%;
}

Это еще одно несовершенное решение, но оно работает.

http://codepen.io/tuxsudo/pen/VYERQJ


11

Я знаю, что здесь есть много ответов, но ... Самый простой способ сделать это с помощью gridвместо, flexа также grid template columnsс repeatи auto fills, где вы должны установить количество пикселей, которое вы дали каждому элементу, 100pxиз вашего кода фрагмента.

.exposegrid {
     display: grid;
     grid-template-columns: repeat(auto-fill, 100px);
     justify-content: space-between;
}
 .exposetab {
     width: 100px;
     height: 66px;
     background-color: rgba(255, 255, 255, 0.2);
     border: 1px solid rgba(0, 0, 0, 0.4);
     border-radius: 5px;
     box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
     margin-bottom: 10px;
}
<div class="exposegrid">
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
   <div class="exposetab"></div>
</div>


2
Это правильное решение для выравнивания элементов последней строки.
a.barbieri

Я согласен, правильно использовать сетку. Это может быть достигнуто с помощью flexbox, но намного чище использовать сетку.
nbarth

6

Да.! Мы можем, но с некоторыми медиа-запросами & Максимальное количество столбцов предопределено .

Здесь я использую 4 столбца. Проверьте мой код:

.container {
  display: flex;
  display: -webkit-flex;
  display: -moz-flex;
  flex-flow: row wrap;
  -webkit-flex-flow: row wrap;
  -moz-flex-flow: row wrap;
}

.container .item {
  display: flex;
  display: -webkit-flex;
  display: -moz-flex;
  justify-content: center;
  -webkit-justify-content: center;
  -moz-justify-content: center;
  flex-basis: 25%; //max no of columns in %, 25% = 4 Columns
}

.container .item .item-child {
  width: 130px;
  height: 180px;
  background: red;
  margin: 10px;
}

@media (max-width: 360px) {
  .container .item {
    flex-basis: 100%;
  }
}

@media (min-width:360px) and (max-width: 520px) {
  .container .item {
    flex-basis: 50%;
  }
}

@media (min-width:520px) and (max-width: 680px) {
  .container .item {
    flex-basis: 33.33%;
  }
}
<div class="container">

  <div class="item">
    <div class="item-child">1</div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>
  <div class="item">
    <div class="item-child"></div>
  </div>

</div>

ПРИМЕЧАНИЕ
1) Нет необходимости создавать дочерний div. Это может быть любой другой тег, такой как 'img' r, что вы хотите.
2) Если вы хотите, чтобы больше столбцов, измените медиазапросы и максимальное количество столбцов no.of.


Это создает только 3 в последнем IE
Akxe

6

Если вам нужна сетка с некоторым пространством между элементами и элементами, начинающимися без начального пробела, то это простое решение работает:

.grid {
    display: flex;
    flex-flow: row wrap;
    margin: 0 -5px; // remove the inital 5px space
    width: auto;
}
.grid__item {
    width: 25%;
    padding: 0 5px; // should be same as the negative margin above.
}

Если вы хотите получить начальное пространство в 5px, просто удалите отрицательное поле :) Просто.

https://jsfiddle.net/b97ewrno/2/

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


1
Удивлен, что больше нет голосов. Это красивый подход, который принадлежит музею Flex.
Эдуардо Ла Хоз Миранда

1
@EduardoLaHozMiranda спасибо! Но почему "музей"? IE11 не поддерживает сетку CSS, и большинство сайтов все еще должны поддерживать это. + Некоторые крупные разработчики внешнего интерфейса все еще утверждают, что существуют различные варианты использования grid против flexbox. Но, возможно, вы просто имели в виду, что это должно быть важной частью истории Интернета: D
OZZIE

1
Лол да Я был взволнован в то время. Просто имел в виду, что это был отличный и минимальный подход к этой проблеме.
Эдуардо Ла Хоз Миранда

@dencey, вам не нужно знать, что для этого решения это 25%, то есть максимум 4 на строку, но вы можете использовать любой процент, какой захотите
OZZIE

@ OZZIE Я имею в виду, что ширина элемента фиксирована (например, 100 пикселей), но ширина контейнера динамическая, поэтому количество элементов в строке является динамическим.
Дэнси

4

Если вы хотите выровнять последний элемент по сетке, используйте следующий код:

Сетка контейнер

.card-grid {
  box-sizing: border-box;
  max-height: 100%;
  display: flex;
  flex-direction: row;
  -webkit-box-orient: horizontal;
  -webkit-box-direction: normal;
  justify-content: space-between;
  align-items: stretch;
  align-content: stretch;
  -webkit-box-align: stretch;
  -webkit-box-orient: horizontal;
  -webkit-box-direction: normal;
  -ms-flex-flow: row wrap;
  flex-flow: row wrap;
}

.card-grid:after {
  content: "";
  flex: 1 1 100%;
  max-width: 32%;
}

Предмет в сетке

.card {
  flex: 1 1 100%;
  box-sizing: border-box;
  -webkit-box-flex: 1;
  max-width: 32%;
  display: block;
  position: relative;

}

Хитрость заключается в том, чтобы установить максимальную ширину элемента, равную максимальной ширине .card-grid: after.

Живая демоверсия на Codepen


Ктулу благословляет вас и ваш компьютер
L422Y

3
Этот подход не работает, если размер карточки фиксирован и количество карточек в каждом ряду неизвестно. codepen.io/zendu/pen/WXNGvo
zendu

3

Можно использовать «flex-start» и добавлять поля вручную. Это требует некоторого математического взлома, но, безусловно, это легко сделать, и его легко использовать с таким препроцессором CSS, как LESS.

Смотрите, например, этот МЕНЬШИЙ миксин:

.flexboxGridMixin(@columnNumber,@spacingPercent) {
  @contentPercent: 100% - @spacingPercent;
  @sideMargin: @spacingPercent/(@columnNumber*2);
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: flex-start;
  > * {
    box-sizing: border-box;
    width: @contentPercent/@columnNumber;
    margin-left: @sideMargin;
    margin-right: @sideMargin;
  }
}

И тогда его легко можно использовать для отображения адаптивного макета сетки:

ul {
  list-style: none;
  padding: 0;
  @spacing: 10%;
  @media only screen and (max-width: 499px) { .flexboxGridMixin(1,@spacing); }
  @media only screen and (min-width: 500px) { .flexboxGridMixin(2,@spacing); }
  @media only screen and (min-width: 700px) { .flexboxGridMixin(3,@spacing); }
  @media only screen and (min-width: 900px) { .flexboxGridMixin(4,@spacing); }
  @media only screen and (min-width: 1100px) { .flexboxGridMixin(5,@spacing); }
}

li {
  background: pink;
  height: 100px;
  margin-top: 20px;
}

Вот пример

http://codepen.io/anon/pen/YyLqVB?editors=110


Вы никогда не используете @contentPercent. Вы собирались?
neverfox

ширина: @ contentPercent / @ columnNumber;
Realtebo

ВОТ ЭТО ДА ! Я действительно впечатлен этим решением. Я постараюсь приспособиться к моей ситуации
realtebo

3

Эта проблема была решена для меня с помощью сетки CSS,

Это решение применимо, только если у вас фиксированное количество столбцов, т.е. нет. элементов для отображения в одной строке

-> используя сетку, но не указав количество строк, так как количество элементов увеличивается, оно переносится в столбцы и динамически добавляет строки, в этом примере я указал три столбца

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

.grid-class{
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  column-gap: 80px;
}


1

Эта версия является лучшим способом для блоков с фиксированной шириной:

http://codepen.io/7iomka/pen/oxxeNE

В остальных случаях - версия Далгарда

http://codepen.io/dalgard/pen/Dbnus

body {
  padding: 5%;
}

div {
  overflow: hidden;
  background-color: yellow;
}

ul {
  display: flex;
  flex-wrap: wrap;
justify-content:center;
  margin: 0 -4px -4px 0;
  list-style: none;
  padding: 0;
}

li {
  flex: 1 0 200px;
  height: 200px;
  max-width:200px;
  min-width:200px;
  border-right: 4px solid black;
  border-bottom: 4px solid black;
  background-color: deeppink;
}
li:empty {
  height: 0;
  border: none;
}

*,
:before,
:after {
  box-sizing: border-box;
}
<div>
  <ul>
    <li>a</li>
    <li>b</li>
    <li>c</li>
    <li>d</li>
    <li>e</li>
    <li>f</li>
    <li>g</li>
    <li>h</li>
    <li>i</li>
    <li>j</li>
    <li>k</li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
  </ul>
</div>


0

Есть способ без flexbox, хотя вам нужно будет выполнить следующие условия. 1) Контейнер имеет прокладку. 2) Предметы одинакового размера, и вы точно знаете, сколько вы хотите за строку.

ul {
  padding: 0 3% 0 5%;
}
li {
  display: inline-block; 
  padding: 0 2% 2% 0;
  width: 28.66%;
}

Чем меньше отступ с правой стороны контейнера, тем больше отступ справа от каждого элемента списка. Если предположить, что другие элементы в том же родительском объекте, что и у объекта списка, заполнены 0 5%, они будут заполнены ими. Вы также можете отрегулировать процентное соотношение, чтобы получить максимальный размер поля, или использовать для вычисления значений px.

Конечно, вы можете сделать то же самое без заполнения контейнера, используя nth-child (IE 9+) для удаления полей в каждом третьем блоке.


0

Используя flexbox и несколько медиазапросов, я сделал этот небольшой обходной путь: http://codepen.io/una/pen/yNEGjv (это немного странно, но работает):

.container {
  display: flex;
  flex-flow: row wrap;
  justify-content: flex-start;
  max-width: 1200px;
  margin: 0 auto;
}

.item {
  background-color: gray;
  height: 300px;
  flex: 0 30%;
  margin: 10px;

  @media (max-width: 700px) {
     flex: 0 45%;
  }

  @media (max-width: 420px) {
    flex: 0 100%;
  }

  &:nth-child(3n-1) {
    margin-left: 10px;
    margin-right: 10px;
  }
}

0

Я сделал для этого миксины SCSS.

@mixin last-row-flexbox($num-columns, $width-items){

  $filled-space: $width-items * $num-columns;
  $margin: calc((100% - #{$filled-space}) / (#{$num-columns} - 1));

  $num-cols-1 : $num-columns - 1;

  &:nth-child(#{$num-columns}n+1):nth-last-child(-n+#{$num-cols-1}) ~ & {
    margin-left: $margin;
  }
  @for $i from 1 through $num-columns - 2 { 
    $index: $num-columns - $i;
    &:nth-child(#{$num-columns}n+#{$index}):last-child{
      margin-right: auto;
    }
  }
}

Это ссылка codepen: http://codepen.io/diana_aceves/pen/KVGNZg

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

Я надеюсь это тебе поможет.


0

Вот еще пара scss mixins.

Эти миксины предполагают, что вы не собираетесь использовать js-плагины, такие как Isotope (они не соблюдают порядок разметки html, что приводит к нарушению правил CSS).

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

И, кстати, до тех пор, пока вы правильно настроите свойства flex вашего контейнера, вы также можете использовать только flexbox_cell () для элементов, если вам это нужно.

Вот код:

// apply to the container (for ex. <UL> element)
@mixin flexbox_grid($columns, $gutter_width){

  display: flex;
  flex-direction:row;
  flex-wrap:wrap;
  justify-content: flex-start;

  > *{
    @include flexbox_cell($columns, $gutter_width);
  }
}

// apply to the cell (for ex. a <LI> element)
@mixin flexbox_cell($columns, $gutter_width){
  $base_width: 100 / $columns;
  $gutters: $columns - 1;
  $gutter_offset: $gutter_width * $gutters / $columns;

  flex-grow: 0;
  flex-shrink: 1;
  flex-basis: auto; // IE10 doesn't support calc() here

  box-sizing:border-box; // so you can freely apply borders/paddings to items
  width: calc( #{$base_width}% - #{$gutter_offset} );

  // remove useless margins (for cascading breakponts)
  &:nth-child(#{$columns}n){
    margin-right: 0;
  }

  // apply margin
  @for $i from 0 through ($gutters){
    @if($i != 0){
      &:nth-child(#{$columns}n+#{$i}){
        margin-right: $gutter_width;
      }
    }
  }
}

Применение:

ul{
   // just this:
   @include flexbox_grid(3,20px);
}

// and maybe in following breakpoints, 
// where the container is already setted up, 
// just change only the cells:

li{
   @include flexbox_cell(4,40px);
}

Очевидно, что вы должны в конечном итоге установить отступы / margin / width контейнера и нижние поля ячейки и тому подобное.

Надеюсь, поможет!


0

Это довольно забавно, но у меня работает. Я пытался добиться последовательных интервалов / полей.

.grid {
  width: 1024px;
  display: flex;
  flex-flow: row wrap;
  padding: 32px;
  background-color: #ddd;  

  &:after {
    content: "";
    flex: auto;
    margin-left:-1%;
  }

  .item {
    flex: 1 0 24.25%;
    max-width: 24.25%;
    margin-bottom: 10px;
    text-align: center;
    background-color: #bbb;

    &:nth-child(4n+2),
    &:nth-child(4n+3),
    &:nth-child(4n+4) {
      margin-left: 1%;
    }

    &:nth-child(4n+1):nth-last-child(-n+4),
      &:nth-child(4n+1):nth-last-child(-n+4) ~ .item {
        margin-bottom: 0;
    }    

  }
}

http://codepen.io/rustydev/pen/f7c8920e0beb0ba9a904da7ebd9970ae/


0

Похоже, никто не предложил решение flex-grow для последнего пункта. Идея состоит в том, чтобы ваш последний элемент Flex занял все место с помощью flex-grow: 1.

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

.grid > *:last-child {
  flex-grow: 1;
}

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


0

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

Вот разметка:

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

.flex-container:after {
  content: "";
  flex-basis: 30%;
}

1
Чтобы быть более общим: размер flex-based должен быть равен размеру дочерних элементов.
Кристиан

1
Я нашел flex-grow: 0.9вместо flex-basisработ для любого количества столбцов. Протестировано во множестве современных браузеров - в них все работает, но в IE не работает отступ (но работает в Edge0
Patabugen

0

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

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

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

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

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

.flex {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  margin: 1em 0 3em;
  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>


0

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

Пример: 3 элемента подряд, разрыв между элементами 10px

div:last-child:nth-child(3n+2) {
  flex-grow: 1
  margin-left: 10px
}

0

Просто используйте трюк Jquery / Javascript, чтобы добавить пустой div:

if($('.exposegrid').length%3==2){
 $(".exposegrid").append('<div class="exposetab"></div>');
}

-1

О, парень, я думаю, что нашел хорошее решение с минимальным CSS и без JS. Проверьте это:

img {width:100%;}
li {
  display: inline-block;
  width:8em;
  list-style:none;
}
ul {text-align: justify;}
<ul>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li>
    <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
  </li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>

Ключевым моментом здесь является помнить, что то, что мы пытаемся достичь, это именно то, что text-align: justifyделает!

Пустые элементы в HTML созданы для того, чтобы последняя строка отображалась идеально, без изменения внешнего вида, но может не потребоваться, учитывая то, что вы пытаетесь достичь. Для достижения идеального баланса в любой ситуации вам нужно как минимум x-4 пустых элемента, x - количество отображаемых элементов, или n-2, n - количество отображаемых столбцов.


-1

Просто добавьте несколько поддельных предметов с такими же свойствами, за исключением высоты, установленной в 0px в конце.


Добавление поддельных предметов - плохая практика во всех отношениях. Вы не должны заполнять DOM вещами только для того, чтобы взламывать css, если это не обязательно. По многим причинам, от доступности, до переполнения кодовой базы странными вещами, до усложнения логики, чтобы понять и составить список. Не рекомендуйте хаки, если вы явно не скажете, что это может быть плохим решением или для этого есть особый случай.
Эксапсы

-4

Вы хотите выровнять

использовать align-content: flex-start;вместоjustify-content: space-between;

это тянет элементы в последнюю строку слева, а также равномерно распределяет пространство,

.container {
  display: flex;
  flex-flow: row wrap;
  align-content: flex-start;
  /*justify-content: space-between; remove this line!!!! */ 
}

https://codepen.io/anon/pen/aQggBW?editors=1100


Решение ДэнАндерсон НЕ ДИНАМИЧНОЕ. ПЕРИОД !!

когда ширина элемента изменена с 25 на 28, Дэн Андерсон пропускает пробел между изображениями

ДэнАндерсон: https://codepen.io/anon/pen/ZwYPmB?editors=1100

динамический: https://codepen.io/anon/pen/aQggBW?editors=1100

вот что я пытался сказать. Данс взломан .....


-7

Я смог сделать это justify-content: space-betweenна контейнере

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