Flex-box: вирівняйте останній ряд до сітки


378

У мене простий макет флеш-коробки з контейнером типу:

.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/…
Sebastien Lorber

5
Також можна скористатися новим модулем css grid - у якого немає цієї проблеми
Danield


1
Я додав загальне рішення JS для тих випадків, коли ширина дочірніх змінних, а також кількість елементів у рядковій змінній.
дао

Відповіді:


416

Додайте, ::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
Чи можна було б змусити його якось працювати з простором навколо?
Том

60
@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;}і я змінив максимальну ширину за допомогою змін запитів медіа, щоб сітка була ідеальною на всі ширини.
Колін Вісман

160

Однією з методик було б вставлення декількох зайвих елементів (стільки ж, скільки максимум елементів, які ви коли-небудь очікуєте мати підряд), які мають нульову висоту. Простір все ще розділений, але зайві рядки руйнуються ні до чого:

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
На жаль, це забруднює розмітку несемантично, але цілком працює. : SI хотілося б, щоб я знав будь-який інший спосіб повторити цю поведінку, флексбокс чи іншим способом, який не вимагав несемантичних елементів.
Райан Норбауер

33
Домовились, це брудно, але це працює, і менш хакі, ніж багато хаків. Скажіть, я використовую його до тих пір, поки :: after (12) не отримає підтримку, або вони додадуть додаткові варіанти виправдання. Це справжній ганьба, оскільки те, як виправдовує функцію flexbox на даний момент, просто невірно! Якби ви виправдовували абзац тексту, ви ніколи не намагалися б виправдати останній рядок. Напевно, це був варіант, я не можу повірити, що вони пропустили це.
Codemonkey

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

8
@Codemonkey Ісус. Я тільки почав використовувати флексбокс, думаючи, як позбудусь усіх цих хакків, призначених для вирівнювання цих вбудованих блоків всередині сітки, а тепер виявляється, що це просто неможливо! Я потрапив у цей блок одразу, досягнувши меж, за якими я думав, що навряд чи досягти щасливого вирішення всіх цих старих нерозв'язних проблем CSS. Думаю, не так швидко. Для правильного вертикального центрування знадобилося лише 20 років - ми, звичайно, можемо почекати. Ісусе, це здається таким простим завданням ...
Андрій

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

108

Як уже згадували інші афіші - немає чіткого способу вирівняти останній ряд з флексиком (принаймні, згідно з поточною специфікацією)

Однак для чого це варто: З модулем компонування сітки CSS це напрочуд легко виготовити:

В основному відповідний код зводиться до цього:

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- яка (для макетів у 1 рядок) згортає порожні доріжки до 0 - змушує елементи розширюватися зайняти залишок місця). Це призведе до виправданого "проміжку між" 'макет, коли в сітці є лише один рядок, який у нашому випадку не є тим, що ми хочемо (перегляньте цю демонстрацію, щоб побачити різницю між ними)'.

3) Встановіть прогалини / жолоби для рядків та стовпців сітки - тут, оскільки потрібно макет "проміжку між" - розрив насправді буде мінімальним зазором, оскільки він зростатиме у міру необхідності.

4) Подібно до флексбоксу.

Codepen Demo (Змініть розмір, щоб побачити ефект)


4
Приємне рішення. Проблема полягає лише в тому, що він не працює з IE10 / 11.
zendu

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

4
У світлі сучасних можливостей це тепер має бути прийнятою відповіддю. Використання :afterпсевдоелемента може призвести до небажаних результатів у кращих випадках.
Пол

2
@ Danield ця пропозиція мені дуже допомогла, дякую!
Крис

4
Це має бути прийнятою відповіддю. Я б поєднав це з 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>

8
це цікаво, але не зовсім правильно. проблема виникає, коли ви маєте справу з більш ніж двома елементами в нижньому рядку - простір, який виникає між елементами у верхньому ряду, ніколи не з’являється на останньому; елементи скріплені між собою, нехтуючи оригінальною корисністю між пробілом.
Джон Haugeland

ще краще, якщо ви використовуєте 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 Я думаю, що "техніка" - це справедливий опис моєї відповіді. Це, безумовно, спрацювало як рішення для багатьох людей, у тому числі і до особи, що ставила запит.
dalgard

2
@dalgard Це не змінює того факту, що Flexbox не надає мовних конструкцій, щоб виконувати те, що запитують. Крім того, я заперечую, що додавання підроблених елементів є надзвичайно брудною практикою, прямо там, де використовуються таблиці для компонування.
cimmanon

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

Я згоден, правильним способом є використання сітки. Цього можна досягти за допомогою флексокса, але набагато чистіше використовувати сітку.
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) Не потрібно створювати дочірню поділку. Це може бути будь-який інший тег, наприклад 'img' r що завгодно
.


Це створює лише 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-сітку, і більшість сайтів все ще потребують цього. + Деякі великі таймери в розробці інтерфейсу все ще стверджують, що існують різні випадки використання для сітки проти флексбоксу. Але, можливо, ви просто мали на увазі, що це має бути важливою частиною історії веб-сторінок: D
OZZIE

1
Лол, так. Я тоді був схвильований. Щойно означало, що це велике і мінімальне рішення цієї проблеми.
Едуардо Ла Хос Міранда

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

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

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


cthulu благословляє вас і ваш комп'ютер
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

Існує спосіб без флешбоксу, хоча вам потрібно буде відповідати наступним умовам. 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.

@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

Ось ще пара місин.

Ці міксини припускають, що ви не збираєтесь використовувати плагіни js типу Isotope (вони не дотримуються порядку розмітки html, таким чином, псують правила css nth).

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

І до речі, доки ви правильно налаштуєте властивості гнучкості контейнера, ви можете також використовувати лише 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);
}

Очевидно, ви з часом вирішите встановити прокладку / маржу / ширину контейнера та нижню межу комірки тощо.

Сподіваюся, це допомагає!


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-зростання: 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
Щоб бути більш загальним: розмір гнучкої основи повинен дорівнювати розміру дітей.
Крістіан Тоффоло

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

0

Припустимо:

  • Ви хочете 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 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 елементи підряд, проміжок між елементами 10 пікселів

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

Просто додайте кілька підроблених елементів з однаковими властивостями, за винятком висоти, встановленої до 0 пікселів до кінця.


Додавання підроблених предметів є поганою практикою в усіх способах. Ви не повинні заповнювати 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


Рішення danAnderson НЕ ДИНАМІЧНИЙ .PERİOD !!

при зміні ширини предмета з 25 на 28 дан Андерсон втрачає простір між зображеннями

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