【问题标题】:Can flexbox divide items evenly on multiple rows?flexbox可以在多行上平均划分项目吗?
【发布时间】:2014-03-31 21:26:42
【问题描述】:

我玩过响应式 flexbox 网格,没有媒体查询。

http://jsbin.com/qurumisu/1(重新缩放窗口以查看其工作原理)

它每行可以容纳尽可能多的弹性项目,并均匀地拉伸它们的宽度以填满整行。但是,这对“孤立”项目没有帮助。如果第一行适合 5/6 个项目,则第二行只剩下一个,使其伸展得比它的兄弟姐妹要宽得多。我宁愿通过将元素按所需的行数平均分配来避免这种行为。

这可能吗?

【问题讨论】:

  • Flexbox 不是网格系统,至少不是 CSS 中的网格系统。
  • @cinnamon:我知道。然而,css 中有很多东西并不打算像现在这样使用。例如 CSS 精灵。这仍然解决了一个大问题:)

标签: css flexbox


【解决方案1】:

不,没有媒体查询调整 flex-basis 值。拉伸和环绕的 Flex 项目试图最大化每行的项目数量。

您可能需要考虑改用多列模块,它会尝试在所有创建的列中平均分配元素:

.foo {
    columns: 100px;
}

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

【讨论】:

  • 我不能为此目的使用多列,但是谢谢 :) 有一个专门用于网格的新 css 功能,它可能会帮助我解决这个问题,尽管我认为不会。
【解决方案2】:

这是我为 this question 编写的 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>

【讨论】:

  • 我建议使用媒体查询,例如 twitter bootstraps adaptive grid system,而不是自定义 javascript 布局。
  • 请注意,这也是在 DOM 中注入 CSS,而不是直接通过 JS 使用 CSSOM。此外,它依赖于 jQuery,所以除非你已经在使用它,否则你不能使用这个解决方案。
【解决方案3】:

我一直在寻找完全相同的东西(在 flex-wrap 东西中排列图像缩略图)。你的样本给了我一些方向,我玩了一下,想出了以下内容:

好吧,如果您愿意在 HTML 代码中添加一些额外的标记,那确实是可能的。假设我可以在全屏上显示n 项目,我在容器末尾添加了&lt;div class="hidden-item"&gt;n-1 项目并修改了CSS 代码,使这些隐藏项目具有相同的宽度 em> 但没有高度。这样,它们也会环绕,迫使最后一个项目收缩,而不会增加容器的高度。

结果在这里: http://output.jsbin.com/qaxatujaho/1

【讨论】:

  • 虽然这需要大量样板代码并且不是我真正想要的,但它确实提供了一个我没有想到的实用且以前未记录的替代方案。谢谢!
  • 我知道这已经很老了,但我一直在寻找几个小时来解决这个问题。您的解决方案非常适合我的情况。
【解决方案4】:

我遇到了类似的情况,但选择了与您要求的解决方案不同的解决方案。我没有尝试沿所有行和列平均分配项目的数量,而是在它们上设置了一个 max-width 属性,这样它们就不会占据整个行的空间。

【讨论】:

  • 显然我知道最大宽度。当我问这个问题时,所有 css 网格框架都使用了 max-width,我试图摆脱它,因为它不是很灵活并且需要大量的断点。
猜你喜欢
  • 1970-01-01
  • 2017-09-11
  • 1970-01-01
  • 2021-04-23
  • 1970-01-01
  • 2018-06-16
  • 1970-01-01
  • 2020-12-05
  • 1970-01-01
相关资源
最近更新 更多