首页 文章

CSS-only砌体布局

提问于
浏览
67

我需要实现一个相当普遍的磨坊砌体布局 . 但是,出于多种原因,我不想使用JavaScript来执行此操作 .

enter image description here

参数:

  • 所有元素都具有相同的宽度

  • 元素的高度无法在服务器端计算(图像加上各种文本量)

  • 如果必须,我可以使用固定数量的列

有一个简单的解决方案,适用于现代浏览器,the column-count property.

该解决方案的问题是元素按列排序:

enter image description here

虽然我需要按行排序元素,至少大约:

enter image description here

我试过的方法不起作用:

现在我可以更改服务器端渲染并重新排序项目数除以列数的项目,但是如果可能的话,'s complicated, error-prone (based on how browsers decide to split the item list into columns), so I' d喜欢避免它 .

是否有一些新奇的flexbox魔法可以实现这一目标?

1 回答

  • 100

    Flexbox

    Flexbox无法实现动态砌体布局,至少不能以干净有效的方式进行 .

    Flexbox是一维布局系统 . 这意味着它可以沿水平或垂直线对齐项目 . Flex项目仅限于其行或列 .

    真正的网格系统是二维的,这意味着它可以沿水平和垂直线对齐项目 . 内容项可以跨行和列同时跨越,灵活项无法执行 .

    这就是Flexbox构建网格的能力有限的原因 . 这也是为什么W3C开发了另一种CSS3技术Grid Layout的原因 .


    换行

    在具有 flex-flow: row wrap 的Flex容器中,flex项必须换行到新行 .

    这意味着 a flex item cannot wrap under another item in the same row .

    enter image description here

    请注意上面div#3如何包装在div#1下面,创建一个新行 . 它不能包裹在div#2下面 .

    因此,当物品不是行中最高的时,剩余的空白区域会产生难看的间隙 .

    enter image description here


    列换行

    如果切换到 flex-flow: column wrap ,则可以更好地实现类似网格的布局 . 但是,列方向容器有四个潜在的问题:

    因此,在这种情况下,列方向容器不是一种选择,在许多其他情况下也是如此 .


    CSS Grid,项目维度未定义

    如果可以预先确定内容项的各种高度,网格布局将是您问题的完美解决方案 . 所有其他要求都在Grid的容量范围内 .

    必须知道网格项的宽度和高度才能缩小与周围项目的间隙 .

    因此,在这种情况下,Grid是构建水平流动砌体布局的最佳CSS所必需的 .

    实际上,在CSS技术到来之前能够自动缩小差距,CSS通常没有解决方案 . 这样的事情可能需要回流文档,所以我不确定它会有多么有用或有效 .

    你需要一个脚本 .

    JavaScript解决方案倾向于使用绝对定位,它从文档流中删除内容项,以便无间隙地重新排列它们 . 以下是两个例子:

    Masonry是一个JavaScript网格布局库 . 它的工作原理是根据可用的垂直空间将元素放置在最佳位置,有点像石膏在墙上贴合石头 . 来源:http://masonry.desandro.com/

    [Pinterest]真的是一个很酷的网站,但我觉得有趣的是这些拼图是如何布局的......所以本教程的目的是自己重新创建这个响应式块效果...来源:https:// benholland.me/javascript/2012/02/20/how-to-build-a-site-that-works-like-pinterest.html


    CSS Grid已定义项目维度

    对于已知内容项的宽度和高度的布局,这里是纯CSS中水平流动的砖石布局:

    grid-container {
      display: grid;                                                /* 1 */
      grid-auto-rows: 50px;                                         /* 2 */
      grid-gap: 10px;                                               /* 3 */
      grid-template-columns: repeat(auto-fill, minmax(30%, 1fr));   /* 4 */
    }
    
    [short] {
      grid-row: span 1;                                             /* 5 */
      background-color: green;
    }
    
    [tall] {
      grid-row: span 2;
      background-color: crimson;
    }
    
    [taller] {
      grid-row: span 3;
      background-color: blue;
    }
    
    [tallest] {
      grid-row: span 4;
      background-color: gray;
    }
    
    grid-item {
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 1.3em;
      font-weight: bold;
      color: white;
    }
    
    <grid-container>
      <grid-item short>01</grid-item>
      <grid-item short>02</grid-item>
      <grid-item tall>03</grid-item>
      <grid-item tall>04</grid-item>
      <grid-item short>05</grid-item>
      <grid-item taller>06</grid-item>
      <grid-item short>07</grid-item>
      <grid-item tallest>08</grid-item>
      <grid-item tall>09</grid-item>
      <grid-item short>10</grid-item>
      <grid-item tallest>etc.</grid-item>
      <grid-item tall></grid-item>
      <grid-item taller></grid-item>
      <grid-item short></grid-item>
      <grid-item short></grid-item>
      <grid-item short></grid-item>
      <grid-item short></grid-item>
      <grid-item tall></grid-item>
      <grid-item short></grid-item>
      <grid-item taller></grid-item>
      <grid-item short></grid-item>
      <grid-item tall></grid-item>
      <grid-item short></grid-item>
      <grid-item tall></grid-item>
      <grid-item short></grid-item>
      <grid-item short></grid-item>
      <grid-item tallest></grid-item>
      <grid-item taller></grid-item>
      <grid-item short></grid-item>
      <grid-item tallest></grid-item>
      <grid-item tall></grid-item>
      <grid-item short></grid-item>
    </grid-container>
    

    jsFiddle演示


    How it works

    repeat表示法定义了重复列(或行)的模式 .

    auto-fill函数告诉网格尽可能多的列(或行)排列而不会溢出容器 . (这可以为flex布局的 flex-wrap: wrap 创建类似的行为 . )

    minmax()函数设置最小和最大大小每列(或行)的范围 . 在上面的代码中,每列的宽度至少为容器的30%,并且最大可用空间 .

    fr unit表示网格容器中可用空间的一小部分 . 它's comparable to flexbox' s flex-grow 属性 .

    • 使用grid-rowspan,我们告诉网格项目它们应跨越多少行 .

    Browser Support for CSS Grid

    • Chrome - 2017年3月8日全面支持(第57版)

    • Firefox - 截至2017年3月6日全面支持(第52版)

    • Safari - 截至2017年3月26日全面支持(版本10.1)

    • Edge - 截至2017年10月16日全面支持(第16版)

    • IE11 - 不支持当前规范;支持过时的版本

    这是完整的图片:http://caniuse.com/#search=grid


    Cool grid overlay feature in Firefox

    在Firefox开发工具中,当您检查网格容器时,CSS声明中有一个很小的网格图标 . 单击它会在页面上显示网格的轮廓 .

    enter image description here

    更多细节:https://developer.mozilla.org/en-US/docs/Tools/Page_Inspector/How_to/Examine_grid_layouts

相关问题