Выровнять по левому краю последнюю строку flexbox, используя пробел между полями и полями
У меня есть неизвестное количество элементов в контейнере, которые нужно обернуть без полей на внешней стороне, но минимальные поля между ними.
Мне также нужно, чтобы они были оправданы с помощью space-between
и последней строки, выровненной слева.
Я пытаюсь сделать это с помощью flexbox следующим образом:
.outside {
border: 1px solid black;
}
.container {
margin: -5px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.container:after {
content: '';
flex: auto;
}
.box {
background: red;
width: 50px;
height: 50px;
margin: 5px;
}
<div class="outside">
<div class="container">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
</div>
Ответы
Ответ 1
Последнее выравнивание строк является общей проблемой с flexbox.
Один из способов рассмотрения - использовать невидимые элементы гибкости после последнего видимого элемента. Короче говоря, я просто называю их "trailing phantom items".
.outside {
border: 1px solid black;
}
.container {
margin: -5px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.container:after {
content: '';
flex: auto;
}
.box {
background: red;
width: 50px;
height: 50px;
margin: 5px;
}
.hidden {
visibility: hidden;
margin: 0 5px;
height: 0;
}
<div class="outside">
<div class="container">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box hidden"></div>
<div class="box hidden"></div>
<div class="box hidden"></div>
<div class="box hidden"></div>
<div class="box hidden"></div>
<div class="box hidden"></div>
<div class="box hidden"></div>
<div class="box hidden"></div>
<div class="box hidden"></div>
<div class="box hidden"></div>
<div class="box hidden"></div>
<div class="box hidden"></div>
<div class="box hidden"></div>
</div>
</div>
Ответ 2
Майкл прав, что проблема в том, что вы не можете сделать space-between
, а затем выбрать последнюю строку, которая будет flex-start
. Часть, которая торчит для меня, является указанной шириной. Это важно?
Если нет, обычным способом сделать это будет использование медиа-запросов для управления количеством отображаемых элементов в строке. Вы можете настроить множество шагов медиа-запросов, чтобы убедиться, что элементы не слишком растягиваются, но таким образом пространство между точками совпадает с вашими обычными решетками сетки, и это заставляет проблему "последних строк" уйти. Думаете, что это сработает?
Пример: http://codepen.io/anon/pen/JbpPKa
Ответ 3
Переполнение стека не позволит мне комментировать ответ Michael_B, но я хотел бы проиллюстрировать, как вычисление количества добавляемых элементов phantom может быть выполнено с помощью JavaScript для всех, кто пытается решить эту проблему.
/**
* @param {Integer} numElements The number of elements you're displaying.
* @param {Number} element Width Width, in pixels, of each element.
* @param {Number} margin Width, in pixels. Your minimum target margin between items. 2x the margin on each individual item.
* @param {Number} containerWidth Width, in pixels, of the containing element.
*/
const getNumPhantomElements = ({numElements, elementWidth, margin, containerWidth}) => {
const elementsPerRow = Math.floor(containerWidth / (elementWidth + margin));
const elementsInLastRow = numElements % elementsPerRow;
const numPhantomElements = elementsPerRow - elementsInLastRow;
return numPhantomElements;
};
В этом случае:
const containerWidth = document.querySelector('.container').offsetWidth;
const numPhantomElements = getNumPhantomElements({
numElements: 21,
elementWidth: 50,
margin: 10, // 2x 5px margin on each box
containerWidth
}); // Append this many elements (output depends on your viewport size)