html - CSS "grid"现代 CSS 布局(无 JS)

标签 html css layout flexbox

想要

我想要一个网格布局。 有点像 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”项的右侧(而不是下方)。

layout

我的尝试

我已经完成了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/

相关文章:

css - 如何使中间框中的内容垂直居中?

javascript - 如何在 P 或 span 标签内附加 ul 标签?

html - 在菜单上方突破其 div 容器的图像

图片下方的 HTML/CSS 文本

javascript - 使用 javascript 复选框事件切换 html 的可见性

javascript - 如何使用纯 css、HTML 和 javascript 自动网格布局?

javascript - 在 react 中动态附加和删除事件监听器

html - 我想在悬停时更改图像的背景颜色

css - CSS fit-content 和 max-content 有什么区别?

CSS/BOOTSTRAP : making element inside the gird (. 容器/.row) 全(屏幕)宽度