首页/文章列表/文章详情

Web前端入门第 48 问:纯 CSS 使用 column 属性实现瀑布流布局

编程知识992025-05-09评论

什么是瀑布流?

看一张图,以下图片来源于花瓣网截图:

如上图所示,瀑布流就是让内容按列显示,自动填充空白。

使用 column 实现瀑布流

源码:

<div class="masonry"> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div></div><style>:root{ --item-bg-1: #ff4757; --item-bg-2: #cea442; --item-bg-3: #18005f; --counter-bg: #dedede;}.masonry { column-count: 1; column-gap: 20px;  counter-reset: item-counter; }@media screen and (min-width: 400px) { .masonry { column-count: 2; }}@media screen and (min-width: 600px) { .masonry { column-count: 3; }}@media screen and (min-width: 800px) { .masonry { column-count: 4; }}@media screen and (min-width: 1200px) { .masonry { column-count: 5; }}.item { box-sizing: border-box; break-inside: avoid; margin: 0 0 20px;  counter-increment: item-counter; position: relative;}.item:before { position: absolute; top: 0; left: 0; padding: 8px 0; min-width: 2em; text-align: center; background-color: var(--counter-bg); content: counter(item-counter);}.item:nth-child(7n+1) { height: 151px; background-color: var(--item-bg-1);}.item:nth-child(7n+2) { height: 187px; background-color: var(--item-bg-2);}.item:nth-child(7n+3) { height: 289px; background-color: var(--item-bg-3);}.item:nth-child(7n+4) { height: 123px; background-color: var(--item-bg-1);}.item:nth-child(7n+5) { height: 234px; background-color: var(--item-bg-2);}.item:nth-child(7n+6) { height: 188px; background-color: var(--item-bg-3);}.item:nth-child(7n+7) { height: 149px; background-color: var(--item-bg-1);}</style>

效果:

视口宽度大于 1200px 时,显示 5 列:

视口宽度在 600px-800px 之间时,显示 3 列:

column 相关属性

column-count

column-count声明显示多少列。默认值为auto,由浏览器自己决定。

column-fill

column-fill控制元素内容分成列时的平衡方式。有效值:auto(按顺序填充列)、balance(仅最后一页内容平均分配到各列)、balance-all(全部分页内容平均分配到各列)。

column-gap

column-gap设置列间隔。默认值normal 表示列间距占用 1em 宽度。

column-rule

column-rule 简写属性,包含 column-rule-width、column-rule-style 和 column-rule-color 。

column-rule-width设置线条宽度。
column-rule-style 与 border-style 一样,支持值:none 、 hidden 、 dotted 、 dashed 、 solid 、 double 、 groove 、 ridge 、 inset 、 outset。
column-rule-color设置线条颜色。

column-span

column-span设置子元素是否跨列显示。有效值:none(不跨列)、all(跨列)。

column-width

column-width设置列的宽度。浏览器会自动调整宽度大小,如果设置的宽度连两列都放不下,会自动变为一列显示(如图三)。

columns

columns 简写属性,可组合设置 column-width 和 column-count 属性。

grid 实现瀑布流

源码:

<div class="masonry"> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div> <div class="item"> </div></div><style>:root{ --item-bg-1: #ff4757; --item-bg-2: #cea442; --item-bg-3: #18005f; --counter-bg: #dedede;}.masonry { display: grid; grid-gap: 20px; grid-auto-flow: dense row; grid-template-columns: repeat(9, 1fr); grid-auto-rows: minmax(50px, auto);  counter-reset: item-counter;}.item { box-sizing: border-box;  counter-increment: item-counter; position: relative;}.item:before { position: absolute; top: 0; left: 0; padding: 8px 0; min-width: 2em; text-align: center; background-color: var(--counter-bg); content: counter(item-counter);}.item:nth-child(7n+1) { grid-row: 1 / 4; background-color: var(--item-bg-1);}.item:nth-child(7n+2) { grid-row: 1 / 3; background-color: var(--item-bg-2);}.item:nth-child(7n+3) { grid-row: 1 / 4; background-color: var(--item-bg-3);}.item:nth-child(7n+4) { grid-row: 4 / 7; background-color: var(--item-bg-1);}.item:nth-child(7n+5) { grid-row: 3 / 9; background-color: var(--item-bg-2);}.item:nth-child(7n+6) { grid-row: 4 / 8; background-color: var(--item-bg-3);}.item:nth-child(7n+7) { grid-row: 7 / 11; background-color: var(--item-bg-1);}</style>

效果:

写在最后

在多列布局方面 column 属性相比于 flex 和 grid 而言,显得更有优势。

虽说 grid 也能做出瀑布流效果,不过需要指定每个网格单元的占用大小。

column 虽然不用控制每个子项的大小,但它的子元素排列顺序是从上到下排列,并不是从左往右,这种情况如果数据存在分页加载时候,就会出现内容重新排列导致内容闪动。

在瀑布流布局这个需求场景下,CSS 多多少少还是有点弱鸡~~必要时候还是只有祭出 JS 。

其他相关资料:

break-*控制多列布局如何中断换列:https://developer.mozilla.org/zh-CN/docs/Web/CSS/break-inside

神弓

前端路引

这个人很懒...

用户评论 (0)

发表评论

captcha