瀑布流(无限加载)4种不同的布局方式

17,492 阅读3分钟

瀑布流的介绍

瀑布流,又称瀑布流式布局。是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部

特点:

  • 固定宽度
  • 参差不齐的布局
  • 以图片为主

瀑布流效果展示:

瀑布流.gif

实现方式

  1. column-count 多栏布局
  2. flex布局
  3. grid布局
  4. absolute布局

column-count 多栏布局

采用CSS的column-count属性实现多栏布局。

实现的代码:

.container {
  padding: 10px;
  column-count: 2;
  column-gap: 10px;
}

column-count表示分栏数目,column-gap表示分栏的间距。这里表示分2栏,两栏之间的间距为10px。

效果:

colum.gif

第二列在滑动的时候会出现抖动。

缺点:排列顺序是先上下后左右,而用户是横排观看,因此无法将优先级较高的项排列在前。无限滚动时由于新元素的加入导致,第二列上面的元素会移动到左边一列的最下面导致出现抖动

flex布局

使用flex布局,将容器设置为flex布局,设置允许换行,容器设定固定宽度。space-evenly:平均分布所有项目之间的间距,并且首尾项目与容器边缘之间的空间大小也相等。

.container {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-evenly;
}

.recommendCard {
  width: 180px;
  height: fit-content;
  margin-bottom: 20px;
  padding: 0;
  border-radius: 4px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

效果:

11.png

上下图片之间的间距的不齐。

缺点:这里发现flex布局是一行一行的,无法实现卡片的等宽不等高,导致每行上下卡片会出现空隙。

flex方法应该有别的方法可以实现,比如按列排列,但是本文没有实现出来。本方法仅展现该代码的实现效果。

absolute布局

通过计算每个card的高度,使用absolute定位动态计算card高度的偏移位置。这也是一些商业瀑布流的常见做法。

优点:精准。

缺点:计算代价大,在计算card高度时,可能会造成大量重排。

Grid方案

Flex布局是轴线布局,只能指定"项目"针对轴线的位置,可以看作是一维布局,Grid 布局则是将容器划分成“行"和“列”,产生单元格,然后指定"项目所在”的单元格,可以看作是二维布局

使用grid布局实现两列排布,简洁方便。默认从上一行结束处开始排布。

通过grid-row-end动态设置每个card的偏移量。

  // 瀑布流,通过设置grid-row-end属性实现
  const cardRefs = useRef();
  const handleSetGridRowEnd = (index: number) => {
    const cardRef = cardRefs.current[index];
    if (!cardRef) return;
    const height = cardRef.offsetHeight;
    // grid-row-end: <line> | <span>;设置元素在网格布局中结束的位置
    cardRef.style.gridRowEnd = `span ${Math.ceil(height)}`;
  };

.container {
  margin: 0 auto;
  display: grid;
  column-gap: 5px;
  padding: 10px;
  justify-items: center;
  grid-template-columns: repeat(2, minmax(180px, 1fr));
}

.recommendCard {
  grid-row-start: auto;
  grid-row-end: span 180;
  width: 180px;
  padding: 5px;
  box-sizing: border-box;
  height: fit-content;
}

实现效果:

grid.gif

实现瀑布流效果,上下图片间距相等,也没有出现抖动。