Правильное выравнивание по ширине контейнера

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

Между тем, если вам не нужно поддерживать IE9-, вы можете использовать прекрасное решение на флексбоксе. И сразу кодпен с решением:

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

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

Казалось бы, задача решена — элементы выравниваются по ширине. Однако если в последней строке элементов будет меньше, чем нужно для её полного заполнения — например, только два блока с шириной в 33%, то эти два блока тоже будут выровнены по ширине, что не очень красиво.

Чтобы блоки в последней строке выравнивались по левому краю, добавим в самый конец контейнера n–1 (помните? n — максимальное количество элементов в одной строке сетки) пустых элементов. Этим элементам зададим следующие стили:

/* Псевдоселектор :empty автоматически выберет пустые элементы */
.grid__item:empty {
  flex: 0 0 33%; /* ширина наименьшего модуля сетки */
  height: 0; /* убедимся в том, что пустые элементы не будет видно в любом случае */
}

На экране этих блоков видно не будет, но браузер будет считать их за полноценные элементы сетки, и если в последней строке останется два видимых элемента, то один из двух пустых блоков подставится в эту же строку и займёт третьего элемента. Этакий элемент-фантом. Таким образом даже при недостатке видимых элементов последняя строка сетки всегда будет заполнена, а значит видимые элементы будут выравниваться по левому краю, что нам и требовалось.

Share
Send
Pin
6 comments
Мимо проходил

Что? Добавлять элементы в разметку только ради оформления? В 21 веке? Не семантично.

Андрей Романов

Если напишете решение этой задачи без добавления лишних элементов, все будут вам благодарны :)

Monochromer

А почему бы не использовать решение с inline-block и text-align: justify?

Мимо проходил

Что может быть проще?

.grid::after {
content: “‘;
flex: 0 0 33.3333%;
}

И добавлять в принципе нужно только один элемент, так как не совсем ожидаемое отображение есть только с двумя элементами, один элемент работает как нужно.

Андрей Романов

Согласен, в случае с сеткой 3×n это отличное решение. Но если элементов в одной строке будет больше трёх, то хоть как придётся добавлять в разметку дополнительные элементы.

Мимо проходил

Собственно о чём это я. Есть же
.grid {
justify-content: flex-start;
}
Заменить оригинальное space-between и всё, готово, можно подавать.

Андрей Романов

Нет же. Задача — сделать сетку с выравниванием элементов по ширине их контейнера. В случае с flex-start они просто будут по левому краю выравниваться.

Мимо проходил

Я попробовал- мне помогло, выглядит ровно так же, как на вашем примере.

Андрей Романов

Выглядит так же, потому что в примере ширина одной колонки — 33.(3)%. Попробуйте сделать ширину колонки меньше и увидите неправильное выравнивание.

Мимо проходил

Ok, признаю: Flexbox- фуфло. Впрочем Grid-layout тоже в некоторых ситуациях не выручает.
21 век на дворе, а нормального способа разметки до сих пор нет *плачу*

Your comment
won’t be published

HTML will not work

Ctrl + Enter
Popular