Может ли flexbox делить элементы равномерно на несколько строк?
Я играл с гибкими сетями flexbox без медиа-запросов.
http://jsbin.com/qurumisu/1 (перетащите окно, чтобы увидеть, как он работает)
Он подходит как можно больше элементов гибкости для каждой строки и равномерно растягивает их ширину, чтобы заполнить всю строку. Однако это не помогает "сиротским" предметам. Если первая строка соответствует 5/6 предметам, для второй линии остается только одна, что делает ее растянутой намного шире, чем ее братья и сестры. Я бы предпочел избежать этого поведения, разделив элементы равномерно на количество требуемых строк.
Возможно ли это?
Ответы
Ответ 1
Нет, не без медиа-запросов, корректирующих значение flex-основы. Элементы Flex, которые растягивают и обертывают, пытаются максимизировать количество элементов, которые соответствуют каждой строке.
Вместо этого вы можете захотеть использовать многоколоночный модуль, который будет пытаться равномерно распределить элементы по всем созданным столбцам:
.foo {
columns: 100px;
}
http://caniuse.com/#feat=multicolumn
Ответ 2
Я искал точно то же самое (выстраивая миниатюры изображений в flex-wrap вещь). Ваш образец дал мне несколько направлений, и я играл с ним немного, и придумал следующее:
Хорошо, если вы захотите добавить некоторую дополнительную разметку в код HTML, это действительно возможно. Предполагая, что я могу показать элементы n
на экране полной ширины, я добавил n-1
элементы <div class="hidden-item">
в конце контейнера и изменил код CSS, чтобы эти скрытые элементы имели одинаковую ширину, но не высоту. Таким образом, они также обертываются, заставляя последний предмет сжиматься, не увеличивая высоту контейнера.
Результат здесь:
http://output.jsbin.com/qaxatujaho/1
Ответ 3
Вот решение для JavaScript, которое я написал для этот вопрос:
var resize = function() {
var container = document.querySelector('#container');
var items = document.querySelectorAll('.item');
var css = document.querySelector('#js-css');
var itemWidth = 100;
var containerWidth = $(container).width();
var perRowCount = Math.floor(containerWidth / itemWidth);
var rowCount = Math.ceil(items.length / perRowCount);
var newPerRowCount = Math.floor(items.length / rowCount);
var newItemWidth = (containerWidth / newPerRowCount) - (parseInt($(items[0]).css('margin')) * 2);
css.innerHTML = '.item { width: ' + newItemWidth + 'px; }';
};
Вы можете запустить функцию resize()
при изменении размера окна просмотра.
Вот пример: (или, альтернативно, JS Bin)
var resize = function() {
var container = document.querySelector('#container');
var items = document.querySelectorAll('.item');
var css = document.querySelector('#js-css');
var itemWidth = 100;
var containerWidth = $(container).width();
var perRowCount = Math.floor(containerWidth / itemWidth);
var rowCount = Math.ceil(items.length / perRowCount);
var newPerRowCount = Math.floor(items.length / rowCount);
var newItemWidth = (containerWidth / newPerRowCount) - (parseInt($(items[0]).css('margin')) * 2);
css.innerHTML = '.item { width: ' + newItemWidth + 'px; }';
};
var increase = function() {
var container = document.querySelector('#container');
$(container).width($(container).width() + 15);
resize();
};
var decrease = function() {
var container = document.querySelector('#container');
$(container).width($(container).width() - 15);
resize();
};
resize();
#container {
justify-content: space-around;
align-items: center;
flex-wrap: wrap;
flex-direction: row;
display: flex;
-webkit-justify-content: space-around;
-ms-justify-content: space-around;
-webkit-align-items: center;
-ms-align-items: center;
-webkit-flex-wrap: wrap;
-ms-flex-wrap: wrap;
-webkit-flex-direction: row;
-ms-flex-direction: row;
display: -webkit-flex;
display: -ms-flex;
width: 450px;
height: auto;
border: 1px solid #8BC34A;
align-self: center;
-ms-align-self: center;
-webkit-align-self: center;
}
.item {
justify-content: center;
margin: 5px;
display: inline-flex;
width: 100px;
height: 50px;
background-color: #03A9F4;
-webkit-justify-content: center;
-ms-justify-content: center;
display: -webkit-inline-flex;
display: -ms-inline-flex;
}
span {
align-self: center;
color: white;
font-family: sans-serif;
font-size: 12px;
-webkit-align-self: center;
-ms-align-self: center;
}
body {
display: flex;
justify-content: center;
flex-direction: column;
}
#title {
display: flex;
color: grey;
font-family: sans-serif;
font-size: 20px;
margin: 10px;
}
#sub-title {
display: flex;
color: grey;
font-family: sans-serif;
font-size: 15px;
margin-bottom: 15px;
}
button {
width: 100px;
height: 40px;
background-color: #03A9F4;
color: white;
align-self: center;
margin: 10px;
}
<!DOCTYPE html>
<html>
<head>
<script src="//code.jquery.com/jquery-2.1.1.min.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<style id="js-css">
</style>
<span id="title">Flexbox Grid</span>
<span id="sub-title">How to make each row have the same number of items?</span>
<div id="container">
<div class="item">
<span>ITEM #1</span>
</div>
<div class="item">
<span>ITEM #2</span>
</div>
<div class="item">
<span>ITEM #3</span>
</div>
<div class="item">
<span>ITEM #4</span>
</div>
<div class="item">
<span>ITEM #5</span>
</div>
<div class="item">
<span>ITEM #6</span>
</div>
</div>
<button onClick="increase()">+</button>
<button onClick="resize()">Resize Items</button>
<button onClick="decrease()">-</button>
</body>
</html>