I've played around with responsive flexbox grids, with no media queries.

http://jsbin.com/qurumisu/1 (rescale the window to see how it works)

It fits as many flex items as it can per row and stretches their width equally to fill the whole line. However, this doesn't help "orphan" items. If the first line fits 5/6 items there is only one left for the second line, making it stretch much wider than it's siblings. I would prefer to avoid this behavior by having the elements divided evenly on the amount of rows required.

Is this possible?

有帮助吗?

解决方案

No, not without media queries adjusting the flex-basis value. Flex items that stretch and wrap attempt to maximize the amount of items that fit on each row.

You may want to consider using the multi-column module instead, which will attempt to equally distribute elements across all of the columns created:

.foo {
    columns: 100px;
}

http://caniuse.com/#feat=multicolumn

其他提示

I was looking for exactly the same thing (lining up image thumbnails in a flex-wrap thing). Your sample gave me some directions and I played with it ab bit and came up with the following:

Well, if you'd be willing to add some extra markup to the HTML code, it is indeed possible. Assuming, that I can show n items on full width screen, I added n-1 items of <div class="hidden-item"> at the end of the container and modified the CSS code so that these hidden items have the same width but no height. This way, they wrap around as well, forcing the last item(s) to shrink, without increasing the height of the container.

Result is here: http://output.jsbin.com/qaxatujaho/1

Here is a JavaScript solution I wrote for this question:

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; }';
};

You can run the resize() function when the viewport is resized.

Here is an example: (or alternatively a 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>

I had a similar situation, but opted for a different solution than the one you asked for. Instead of trying to distribute the amount of items evenly along all rows and columns, I set a max-width property on them so that they don't assume the entire row's space.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top