CSS“网格”布局与现代CSS(无JS)

时间:2015-10-28 09:55:09

标签: html css css3 layout flexbox

WANTED

我想要一个网格布局。 有点像Pinterest,除了物品有固定的高度(所以它应该更容易)。

它应该是响应。应根据视口大小设置列数。

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”项目的右侧(而不是在“a”项目的右侧。

layout

MY ATTEMPT

我已经使用flexbox完成了this layout但是我感觉非常hacky,因为我必须用数学来计算一些边距。另外,我不明白如何控制我的flexbox行之间的垂直空间,因为它似乎与容器高度一起增长。

以下是Codepen上面的LESS mixin:

.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布局吗?或者告诉我解决这个布局问题的最佳,最优雅和最现代的方法是什么?

我不想使用浮点数,可能不是内联块,也不想使用基于JS的解决方案,如Packery / Masonry

请在答案中使用现代CSS,因为我已经知道如何用普通的旧CSS / JS来解决这个问题。我只针对现代浏览器(待定义)

解决方案

这是我的final result,对于有兴趣重复使用此布局的人。

这里也是一个非常好的可视化Flexbox教程:https://scotch.io/tutorials/a-visual-guide-to-css3-flexbox-properties

1 个答案:

答案 0 :(得分:2)

  

我已经使用flexbox完成了这个布局,但是由于我必须使用数学来计算一些边距,所以感觉非常糟糕。

是的,我认为您使用的代码超出了必要的范围,并且没有利用多个flexbox功能。使用flex属性可以简单有效地实现所需的布局。

HTML (在codepen中删除了不必要的外部容器)

<object>

CSS (我为不使用预处理器的人编译了CSS)

<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>

DEMO:http://jsfiddle.net/mk8uksb2/

注意:在原始代码中,行之间的空间相对于视口高度收缩或展开,因为创建Flexbox时,默认规则为align-content: stretch。这意味着布局将扩展以填充容器的大小。在修改后的代码中,我用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; } 覆盖了默认值,它将行打包在容器的开头。

您尝试满足网格的多项要求。我认为修改后的代码涵盖了所有内容:

  • 我想要一个网格布局。
  • ......物品有固定的高度。
  • 它应该是响应。
  • 应根据视口大小设置列数。
  • DOM应该是容器内的子项的简单列表。
  • 我不希望每行包装元素。
  • 项目的排序很重要,因此DOM的“b”项应位于“a”项的右侧。