想要
我想要一个网格布局。 有点像 Pinterest,除了元素有固定的高度(所以它应该容易得多)。
它应该是响应式的。列数应根据视口(viewport)大小设置。
DOM 应该是容器内子项的简单列表。我不希望每一行都有一个包装器元素。我想要的是:
<div class="container">
<div class="item">a</div>
<div class="item">b</div>
<div class="item">c</div>
<div class="item">d</div>
<div class="item">e</div>
<div class="item">f</div>
<div class="item">g</div>
<div class="item">h</div>
<div class="item">i</div>
</div>
项的顺序很重要,因此 DOM 的“b”项应位于“a”项的右侧(而不是下方)。
我的尝试
我已经完成了this layout使用 flexbox 但感觉很老套,因为我必须用数学计算一些边距。另外我不明白如何控制我的 flexbox 行之间的垂直空间,因为它似乎随着容器高度的增长而增长。
这是我对上面 Codepen 的 LESS 混合:
.flexboxGridMixin(@columnNumber,@spacingPercent) {
@contentPercent: 100% - @spacingPercent;
@sideMargin: @spacingPercent/(@columnNumber*2);
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: flex-start;
> * {
box-sizing: border-box;
width: (100% - @spacingPercent)/@columnNumber;
margin-left: @sideMargin;
margin-right: @sideMargin;
}
}
这样的数学运算似乎以某种方式违背了 flexbox 的最初目的,不是吗?
预期的答案
那么,有人可以解释一下如何修复我的 flexbox 布局吗?或者告诉我解决此布局问题的最佳、最优雅和现代的方法是什么?
我不想使用 float ,可能不是内联 block ,也不是基于 JS 的解决方案,如 Packery/Masonry
请在您的答案中使用现代 CSS,因为我已经知道如何使用普通的旧 CSS/JS 解决此问题。我只针对现代浏览器(待定义)
解决方案
这是我的 final result , 对于那些有兴趣重用此布局的人。
这里还有一个非常好的可视化 Flexbox 教程:https://scotch.io/tutorials/a-visual-guide-to-css3-flexbox-properties
最佳答案
I have done this layout using flexbox but it feels quite hacky as I have to compute some margins with maths.
是的,我认为您使用的代码过多,而且没有利用一些 flexbox 功能。使用 flex 属性可以简单高效地实现您想要的布局。
HTML(删除了 codepen 中不必要的外部容器)
<ul>
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
<li>e</li>
<li>f</li>
<li>g</li>
<li>h</li>
<li>i</li>
<li>j</li>
<li>k</li>
</ul>
CSS(我为不使用预处理器的人编译了你的 CSS)
html, body { height: 100%; }
ul {
display: flex;
flex-wrap: wrap;
height: 100%;
list-style: none;
padding: 0;
align-content: flex-start; /* solves vertical margin problem (see note below) */
}
li {
flex: 0 1 200px; /* don't grow, shrink proportionally, start at 200px width */
background: pink;
height: 100px;
line-height: 100px; /* for demo only: center text vertically */
text-align: center; /* for demo only: center text horizontally */
box-sizing: border-box;
margin: 15px;
}
演示:http://jsfiddle.net/mk8uksb2/
注意:在原始代码中,行之间的空间相对于视口(viewport)高度收缩或扩展,因为在创建 flexbox 时,默认规则是 align-content: stretch
.这意味着布局将扩展以填充容器的大小。在修改后的代码中,我使用 align-content: flex-start
覆盖了默认值,它在容器的开头打包行。
您试图满足网格的多项要求。我认为修改后的代码涵盖了所有内容:
- 我想要一个网格布局。
- ...元素具有固定高度。
- 它应该是响应式的。
- 列数应根据视口(viewport)大小设置。
- DOM 应该是容器内子项的简单列表。
- 我不希望每一行都有一个包装器元素。
- 项的顺序很重要,因此 DOM 的“b”项应位于“a”项的右侧。
关于html - CSS "grid"现代 CSS 布局(无 JS),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33387851/