最近项目中涉及到了瀑布流,通过flex布局去实现,为了方便后续的复习,在这里记录一下,也感谢大家可以帮我指出错误哈哈
废话少说,先上代码
.img-container {
box-sizing: border-box;
width: 100%;
// 关键代码:
display: flex;
flex-wrap: wrap;
overflow-y: auto;
gap: 10px;
&::after {
content: '';
flex-grow: 999999999;
}
}
.img-card {
box-sizing: border-box;
border-radius: 8px;
overflow: hidden;
cursor: pointer;
height: 200px;
// 关键代码:
width: auto;
flex-grow: 1;
&:hover {
.img-box {
transform: scale(1.2);
}
}
}
实现思路
通过flex盒子布局,先实现水平方向盒子宽度超出换行:
.img-container {
box-sizing: border-box;
width: 100%;
// 关键代码:
display: flex;
flex-wrap: wrap;
overflow-y: auto;
gap: 10px;
}
.img-card {
box-sizing: border-box;
border-radius: 8px;
overflow: hidden;
cursor: pointer;
height: 200px;
// 关键代码:
width: auto;
&:hover {
.img-box {
transform: scale(1.2);
}
}
}
随后得到这样的效果:
可以看到每行的右边都存在空白,这是因为图片大小和数量不固定的原因,水平方向排不下的时候,由flex-wrap: wrap;的原因会进行换行排列
如果我们想占满这些空白呢,可以图片去占据每一行的剩余空间,这里用到flex-grow: 1属性。
.img-card {
// 关键代码:
flex-grow: 1;
}
flex-grow: 1
的含义
-
flex-grow
属性的值:- 0:该项目不会增长,即使有剩余空间。
- 正整数(如1, 2, 3等):项目将根据这个值的比例来增长,以占用父容器中的剩余空间。例如,
flex-grow: 1
表示如果所有其他flex-grow
值都为 0 ,那么这个项目将占据所有剩余空间。
-
flex-grow: 1
:- 当只有一个弹性盒子项(比如
.img-card
)设置了flex-grow: 1
,它表示这个项目将尝试占用父容器中所有剩余的空间。 - 如果有多个项目同时设置了
flex-grow: 1
,它们将平等地分享可用的剩余空间。例如,如果两个项目都有flex-grow: 1
,它们将各占剩余空间的一半。
- 当只有一个弹性盒子项(比如
- 需要注意:
flex-grow: 1
是针对当前元素所在行的宽度的剩余空间进行比例分配的,这种分配仅限于该元素所在的行。
所以这样就会将每一行都占满,不会留白:
正如上面说的,当只有一个弹性盒子项设置了 flex-grow: 1
,它表示这个项目将尝试占用父容器(或者该行)中所有剩余的空间。所以会出现一个元素占满该行全部宽度,两个盒子就均分该行空白空间宽度的情况。
此时,我们需要他们保持自己的宽度,不用拉伸。
.img-container {
&::after {
content: '';
flex-grow: 999999999;
}
}
创建一个伪元素,伪元素在这里的主要作用是用来创建一个“弹性填充”效果,从而影响 .img-container
内部 .img-card
元素的排列和对齐
占据剩余空间:
由于这是一个相对极大的值(999999999),它会优先获得几乎所有的剩余空间。
flex-grow: 999999999
使得这个伪元素尝试占据所有剩余的可用空间。
剩余的.img-card元素会保持自己的宽度,没有空余的空间,就
不会被拉伸了
当然,伪元素的存在,会出现这样的情况:
这两行都是一样数量和大小的图片,可是布局效果并不一样。
这是因为盒子最后面有伪元素的存在,它占据所有的空白空间,其余的元素就不会被拉伸。
而上面的那一行,其实是平均分配了空白空间,图片拉伸后的效果
如果你想要的瀑布流布局并不关心每一个图片的大小,只是想要可以无限堆叠并占满每一行的效果,这也就无伤大雅了。