瀑布流布局Flex
Flexbox
Flexbox布局到今天已经是使用非常广泛的,也算是很成熟的一个特性。那接下来我们就看Flexbox怎么实现瀑布流布局。如果你从未接触过Flexbox相关的属性,那建议你点击这里阅读。如果你觉得这里信息量过于太多,那强列建议你阅读下面几篇文章,阅读完之后你对Flexbox相关属性会有一个彻底的了解:
上面这几篇文章告诉了你有关于Flexbox的一切:
image接下来回到我们今天的正题当中,使用Flexbox实现瀑布流布局有两种方案。
一个主要的列容器
结构依旧和Multi-columns小节中展示的一样。只是在.masonry
容器中使用的CSS不一样:
.masonry {
display: flex;
flex-flow: column wrap;
width: 100%;
height: 800px;
}
之前在.masonry
中是通过column-count
来控制列,这里采用flex-flow
来控制列,并且允许它换行。这里关键是容器的高度,示例中显式的设置了height
属性,当然除了设置px
值,还可以设置100vh
,让.masonry
容器的高度和浏览器视窗高度一样。记住,这里height
可以设置成任何高度值(采用任何的单位),但不能不显式的设置,如果没有显式的设置,容器就无法包裹住项目列表。
使用Flexbox布局,对于.item
可以不再使用break-inside:avoid
,但其它属性可以是一样。同样的,响应式设置,使用Flexbox实现响应式布局比多列布局要来得容易,他天生就具备这方面的能力,只不过我们这里需要对容器的高度做相关的处理。前面也提到过了,如果不给.masonry
容器显式设置高度是无法包裹项目列表的,那么这里响应式设计中就需要在不同的媒体查询条件下设置不同的高度值:
.masonry {
height: auto;
}
@media screen and (min-width: 400px) {
.masonry {
height: 1600px;
}
}
@media screen and (min-width: 600px) {
.masonry {
height: 1300px;
}
}
@media screen and (min-width: 800px) {
.masonry {
height: 1100px;
}
}
@media screen and (min-width: 1100px) {
.masonry {
height: 800px;
}
}
同样来看一个示例效果:
<iframe id="jmEzEm" src="https://codepen.io/airen/embed/jmEzEm?height=400&theme-id=0&slug-hash=jmEzEm&default-tab=result&user=airen" scrolling="no" frameborder="0" height="400" allowtransparency="true" allowfullscreen="true" class="cp_embed_iframe undefined" style="box-sizing: inherit; width: 940px; overflow: hidden;"></iframe>
这个解决方案有一个最致命的地方,就是需要显式的给.masonry
设置height
,特别对于响应式设计来说这个更为不友好。而且当我们的项目列表是动态生成,而且内容不好控制之时,这就更蛋疼了。那么有没有更为友好的方案呢?
前面说到过Flexbox有两种方案,那咱们先来看方案二,再来回答这个问题。
单独的列容器
这个方案,我们需要对我们的HTML结构做一个变更。变更后的HTML结构看起来像这样:
<div class="masonry">
<div class="column">
<div class="item">
<div class="item__content">
</div>
</div>
<!-- more items -->
</div>
<div class="column">
<div class="item">
<div class="item__content">
</div>
</div>
<!-- more items -->
</div>
<div class="column">
<div class="item">
<div class="item__content">
</div>
</div>
<!-- more items -->
</div>
</div>
不难发现,在div.item
外面包了一层div.column
,这个div.column
称为列表项目的单独容器。在这个解决方案中,.masonry
和.column
都通过display:flex
属性将其设置为Flex容器,不同的是.masonry
设置为行(flex-direction:row
),而.column
设置为列(flex-direction
):
.masonry {
display: flex;
flex-direction: row;
}
.column {
display: flex;
flex-direction: column;
width: calc(100%/3);
}
这里有一个需要注意,在.column
咱们通过calc()
方法来控制每个列的宽度,如果你希望是三列,那么可以设置width: calc(100% / 3)
;实际中根据自己的设计来设置width
:
.masonry {
display: flex;
flex-direction: row;
}
.column {
display: flex;
flex-direction: column;
width: calc(100%/3);
}
这种方案对应的响应式设计,需要在不同的媒体查询下修改width
值,比如:
.masonry {
display: flex;
flex-direction: column;
}
@media only screen and (min-width: 500px) {
.masonry {
flex-direction: row;
}
}
.column {
display: flex;
flex-flow: column wrap;
width: 100%;
}
@media only screen and (min-width: 500px) {
.column {
width: calc(100%/5);
}
}
效果如下:
<iframe id="PpEPWG" src="https://codepen.io/airen/embed/PpEPWG?height=400&theme-id=0&slug-hash=PpEPWG&default-tab=result&user=airen" scrolling="no" frameborder="0" height="400" allowtransparency="true" allowfullscreen="true" class="cp_embed_iframe undefined" style="box-sizing: inherit; width: 940px; overflow: hidden;"></iframe>
从实战结果已经告诉你答案了。只不过在结构上变得冗余一点。
以上摘自大漠w3cplus