添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

最近写了个页面,想到了用瀑布流实现页面布局。在我看来一个合格的横向瀑布流式布局包含以下几个条件:

  • 1、每个内容块高度可以不等,但宽度相等。
    由于内容的不确定性,内容块的高度应根据内容高度伸缩。高度相等的话就变成了网格布局,规整倒是规整,不仅没有瀑布效果,内容的个性也无从体现。
  • 2、内容块应进行横向排序。
    由于是默认的瀑布流式是纵向布局,用户的浏览顺序自上而下。加载的新内容始终排列在最下方,因此整个布局的高度可以无限延展,而宽度始终固定。这就要求内容在有排序需求时,必须从左到右依次填充页面。
  • 3、内容块列数固定。
    内容块的列数应是可控的,在当前 div 下不会因为容器空间不足造成内容块溢出或缩小。三列的瀑布流,就应该始终是三列。

用 flexbox, :nth-child() 和 order 实现 CSS 瀑布流式布局

用 flexbox 制作瀑布流布局乍看似乎很容易:只要用 flex-flow: column wrap 就能实现。问题在于这个方法实现出的内容块会排序错乱:内容块渲染是由上至下,而用户阅读是由左至右,因此用户看到的内容块顺序可能是1, 3, 6, 2, 4, 7, 8, 5之类的。

在 flexbox 里用 column 布局实现在 row 才能达到的排序绝非易事,但加上 :nth-child() order 这两个属性就能做到不依靠 JavaScript ,仅用CSS实现瀑布流式布局。

先上干货总结:假设要渲染三列布局,用 flex-direction: column 实现 row 排序的话,只需要:

html:

<div class="container">
  <div class="item" style="height: 140px"></div>
  <div class="item" style="height: 190px"></div>
  <div class="item" style="height: 170px"></div>
  <div class="item" style="height: 120px"></div>
  <div class="item" style="height: 160px"></div>
  <div class="item" style="height: 180px"></div>
  <div class="item" style="height: 140px"></div>
  <div class="item" style="height: 150px"></div>
  <div class="item" style="height: 170px"></div>
  <div class="item" style="height: 170px"></div>
</div>

css:

/* 让内容按列纵向展示 */
.container {
  display: flex;
  flex-flow: column wrap;
/* 重新定义内容块排序优先级,让其横向排序 */
.item:nth-child(3n+1) { order: 1; }
.item:nth-child(3n+2) { order: 2; }
.item:nth-child(3n)   { order: 3; }
/* 强制使内容块分列的隐藏列 */
.container::before,
.container::after {
  content: "";
  flex-basis: 100%;
  width: 0;
  order: 2;
}

实现效果如下:

android 瀑布流recyclerview上滑位置跳动 瀑布流 css_流式布局

缺点:此用法必须要求container,也就是父元素的高度一定,否则就是竖着一排显示

用column属性实现 CSS 瀑布流式布局

.container {
  column-count: auto;
  column-width: 150px;   //单个子元素宽度
}

实现效果如下:

android 瀑布流recyclerview上滑位置跳动 瀑布流 css_瀑布流_02

缺点:此用法内容是从上到下展示的