css瀑布流的缺陷

104 阅读2分钟

今天小胡给大家总结一下瀑布流的实现方式,并说出它们各自的缺点!废话不多说,开写,打了注释的都是核心实现代码

第一种: column 属性

<style>
    body {
      margin: 4px;
      font-family: Helvetica;
    }
    .masonry {
      /* 设置列数 */
      column-count: 3;
      /* 设置列、行宽 */
      column-gap: 0;
    }
    .item {
      position: relative;
      /* -webkit-column-break-inside: avoid; */
      padding: 2px;
      counter-increment: item-counter;
    }
    img {
      /* 设置图片的宽度(分成 3 列,100% 就为一列的宽度) */
      width: 100%;
      /* 高度自适应 */
      height: auto;
    }
    .item::after {
      position: absolute;
      top: 2px;
      left: 2px;
      width: 24px;
      height: 24px;
      text-align: center;
      line-height: 24px;
      background-color: #000;
      color: #fff;
      content: counter(item-counter);
    }
  </style>

</head>
<body>
  <div class="masonry">
    <div class="item">
      <img src="https://picsum.photos/360/460?random=1">
      <div>11</div>
    </div>
    <div class="item">
      <img src="https://picsum.photos/360/400?random=2">
      <div>22</div>
    </div>
    <div class="item">
      <img src="https://picsum.photos/360/420?random=3">
      <div>33</div>
    </div>
    <div class="item">
      <img src="https://picsum.photos/360/450?random=4">
      <div>44</div>
    </div>
    <div class="item">
      <img src="https://picsum.photos/360/480?random=5">
      <div>55</div>
    </div>
  </div>
</body>

效果:

column.png

缺点:

  1. 先渲染列,而不是渲染行,实际开发中如果有时间排序的需求,这种方案是不可行的
  2. 我们可以看到第四个 item 的子元素都跑到下一列去了,这应该是 column 属性的计算方式产生的问题,解决方法我目前知道的是给 item 设置 -webkit-column-break-inside: avoid; ,让每个 item 的子元素不产生新列,当然这个属性有很大的兼容性问题!

column-break-inside.png

第二种:flex 布局

    body {
      margin: 4px;
      font-family: Helvetica;
    }
    .masonry {
      display: flex;
      /* 设置列项排序 */
      flex-direction: column;
      /* 允许换列 */
      flex-wrap: wrap;
      /* 设置高度 */
      height: 3000px;
    }
    .item {
      position: relative;
      /* 两列的瀑布流 */
      width: 50%;
      padding: 2px;
      box-sizing: border-box;
      counter-increment: item-counter;
    }
    img {
      width: 100%;
      height: auto;
    }
    .item::after {
      position: absolute;
      top: 2px;
      left: 2px;
      width: 24px;
      height: 24px;
      text-align: center;
      line-height: 24px;
      background-color: #000;
      color: #fff;
      content: counter(item-counter);
    }
    /* 下面设置排序方式,因为 flex 布局也是一列一列渲染,如果有时间排序需求就进行排序(下面的只适合两列的瀑布流) */
    .item:nth-child(odd) {
      order: 1;
    }
    .item:nth-child(even) {
      order: 2;
    }

效果:

flexwaterfall.png 缺点:

  1. 要设置高度,而且得设置精准,否则就会出现下面的问题,因为高度不够放最后一张图片,所以换到第三列,而且会导致排序乱掉,这导致了很大的局限性,而且实际开发中数据都是异步的

flexerror.png

-----------------------------------------------------------------------------

flexerror2.png

  1. 列数不会随着游览器的宽度而改变,列数是根据高度来决定的

TR9CONMNN}DF$]5V7BU18.png

总结:css瀑布流还是有很多缺陷的,如果对瀑布流的要求不高,建议使用第一种,flex瀑布流要计算总高度,这个总高度是非常难计算准确的,如果你对瀑布流有要求,例如时间排序等等,只能用 JS 来实现了

本期的内容到这里就结束了,如果你觉得这份文章很有用,别忘了点赞收藏起来,谢谢大家!