一、背景—
本文介绍 5 种瀑布流场景的实现, 大家可以根据自身的需求场景进行选择。
5 种场景分别是:
瀑布流特点
纵向+高度排序
纯 CSS 多列实现,是 最简单的瀑布流写法
纵向+高度排序+根据宽度自适应列数
通过 JS 根据屏幕宽度计算列数, 在 web 端更加灵活的展示瀑布流
横向
纯 CSS 弹性布局实现,是 最简单的横向瀑布流写法
横向+高度排序
横向+高度排序的瀑布流,需要通过 JS 计算每一列高度,损耗性能,但是 可以避免某列特别长的情况,体验更好
横向+高度排序+根据宽度自适应列数
需要通过 JS 计算每一列高度,并根据屏幕宽度计算列数,损耗性能,但是 可以避免某列特别长的情况,并且可以 在 web 端更加灵活的展示瀑布流,体验更好, 是 5 种瀑布流中用户体验最好的
我已经将这 5 种场景的实现封装成 npm 包,npm 包地址:https://www.npmjs.com/package/react-masonry-component2,可以直接在 React 项目中安装使用。
二、介绍—
瀑布流,是比较流行的一种网站 页面布局 ,视觉表现为参差不齐的多栏布局,随着页面 滚动条 向下滚动,这种布局还会不断加载 数据块 并附加至当前尾部。
下图就是一个瀑布流布局的示意图:

三、纵向+高度排序—
纵向+高度排序指的是,每列按照纵向排列,往高度最小的列添加内容,如下图所示。

实现纵向+高度排序瀑布流的方法是 CSS 多列布局。
1. 多列布局介绍
多列布局 指的是 CSS3 可以将文本内容设计成像报纸一样的多列布局,如下实例:
CSS3 的多列属性:
2. 实现思路
瀑布流实现思路如下:
3. 实现代码.css-column{
column-count: 4; //分为4列
.css-columndiv{
break-inside: avoid; // 保证每个子元素渲染完在换行
4. 直接使用 npm 包
npm - react-masonry-component2 的使用方法:
import { Masonry } from 'react-masonry-component2'
export const MyComponent = (args) => {
return (
在线预览
四、纵向+高度排序+根据宽度自适应列数—
在纵向+高度排序的基础上,按照宽度自适应列数。

1. 实现思路
2. 实现代码import{ useCallback, useEffect, useMemo, useState } from 'react'
import{ DEFAULT_COLUMNS_COUNT } from'../const'
exportconstuseHasMounted = => {
const
hasMounted, setHasMounted
= useState( false)
useEffect( => {
setHasMounted( true)
}, )
returnhasMounted
exportconstuseWindowWidth = => {
consthasMounted = useHasMounted
const
width, setWidth
= useState( 0)
consthandleResize = useCallback( => {
if(!hasMounted) return
setWidth( window.innerWidth)
},
hasMounted
useEffect( => {
if(hasMounted) {
window.addEventListener( 'resize', handleResize)
handleResize
return=> window.removeEventListener( 'resize', handleResize)
},
hasMounted, handleResize
returnwidth
exportconstuseColumnCount = (columnsCountBreakPoints: {
: number
}) => {
constwindowWidth = useWindowWidth
constcolumnCount = useMemo( => {
constbreakPoints = (
Object.keys(columnsCountBreakPoints asany) asunknown asnumber
).sort( ( a: number, b: number) => a - b)
letcount =
breakPoints.length > 0
? columnsCountBreakPoints!
: DEFAULT_COLUMNS_COUNT
breakPoints.forEach( ( breakPoint) => {
if(breakPoint < windowWidth) {
count = columnsCountBreakPoints!
breakPoint
})
returncount
},
windowWidth, columnsCountBreakPoints
returncolumnCount
动态定义 style columnCount ,实现根据屏幕宽度自适应列数:
const { columnsCountBreakPoints } = props
const columnCount = useColumnCount(columnsCountBreakPoints)
return (
3. 直接使用 npm 包
npm - react-masonry-component2 的使用方法:
import { Masonry } from 'react-masonry-component2'
export const MyComponent = (args) => {
return (
direction='column'
columnsCountBreakPoints={{
1400: 5,
1000: 4,
700: 3,
}}
在线预览
五、横向—
横向瀑布流指的是,每列按照横向排列,如下图所示。

实现横向瀑布流的方法是 CSS 弹性布局。
1. 弹性布局介绍
弹性布局,是一种当页面需要适应不同的屏幕大小以及设备类型时确保元素拥有恰当的行为的布局方式。
引入弹性盒布局模型的目的是提供一种更加有效的方式来对一个容器中的子元素进行排列、对齐和分配空白空间。
CSS3 的弹性布局属性:
2. 实现思路
瀑布流实现思路如下:
3. 实现代码
瀑布流实现代码如下:
.masonry-flex-wrap{
display: flex;
flex-direction: row;
justify-content: center;
align-content: stretch;
&-column {
display: 'flex';
flex-direction: 'column';
justify-content: 'flex-start';
align-content: 'stretch';
flex: 1;
4. 直接使用 npm 包
npm - react-masonry-component2 的使用方法:
import { Masonry } from 'react-masonry-component2'
export const MyComponent = (args) => {
return (
columnsCountBreakPoints={{
1400: 5,
1000: 4,
700: 3,
}}
在线预览
六、横向+高度排序—
横向+高度排序指的是,每列按照横向排列,往高度最小的列添加内容,如下图所示。

高度排序就需要用 JS 逻辑来做了。
1. 实现思路
2. 实现代码export constgetColumnsSortWithHeight = (
children: React.ReactNode,
columnCount: number
) => {
constcolumns: {
height: number
children: React.ReactNode
} = Array.from({ length: columnCount }, => ({
height: 0,
children: ,
}))
React.Children.forEach(children, ( child: React.ReactNode, index) => {
if(child && React.isValidElement(child)) {
if(index < columns.length) {
columns
index % columnCount
.children.push(child)
columns
index % columnCount
.height += child.props.height
return
constminHeightColumn = minBy(columns, ( a) => a.height) as{
height: number
children: React.ReactNode
minHeightColumn.children.push(child)
minHeightColumn.height += child.props.height
})
returncolumns
3. 直接使用 npm 包
npm - react-masonry-component2 的使用方法:
import { Masonry, MasonryItem } from 'react-masonry-component2'
export const MyComponent = (args) => {
return (
sortWithHeight
columnsCountBreakPoints={{
1400: 5,
1000: 4,
700: 3,
}}
在线预览
七、横向+高度排序+根据宽度自适应列数—
根据宽度自适应列数的做法和纵向场景一致,都是监听 resize 方法,根据屏幕宽度得到该宽度下应该展示的列数,这里不做赘述。

1. 直接使用 npm 包
npm - react-masonry-component2 的使用方法:
import { Masonry } from 'react-masonry-component2'
export const MyComponent = (args) => {
return (
sortWithHeight
direction='column'
columnsCountBreakPoints={{
1400: 5,
1000: 4,
700: 3,
}}
在线预览
小结—
本文介绍了 5 种瀑布流场景的实现:
感兴趣的同学可以到 项目源码 查看完整实现代码。
也可以 下载 直接使用。




