📕 实例:九宫格
九宫格的效果应该是很多页面中都会出现的,尤其是移动端的页面中,经常可以看到几排的 icon 排列着。可能是四列的,也有可能是五列的,这些都无所谓,我们一般统称为宫格,或者九宫格。反正呢,大概就是下面这样的一个布局效果。
很显然,现在看到这个效果是最初始的一个宫格布局情况,样式大概就是这样了。
/*
file: flex_0065.css
九宫格效果图 1
*/
.demo {
border: 1px solid #000;
}
/* 既然是九宫格,那就去掉最后一个 flex 元素吧 */
.item_0 {
display: none;
}
/* 九宫格样式开始 */
.demo {
/* 在 flex 容器超过一行的 flex 元素换行显示 */
flex-wrap: wrap;
}
.item {
/* 让每个 item 元素的宽度初始为 33.33%,其实也就是想让一行三列“均分”一下 */
flex: 33.33%;
/* 由于 item 自身有 padding,为了便于计算所以采用 border-box 的盒模型计算方式 */
box-sizing: border-box;
}
后面的宫格例子我们也将会在这个基础上一点点添加,目前已有的样式作用目的已经通过注释的方式进行了描述。简单来说就是,希望在 flex 容器中一行显示三列宽度相同的 flex 元素,如超过 flex 容器的部分则换行显示。
宫格间添加间距
现在每个宫格都是相邻在一起的,一般而言为了能够美观,每个宫格之间都是会添加一些间距来显示。在前面我们了解过,在 flex 弹性布局中,可以使用 justify-content
属性让 flex 元素在容器中产生有间隙的布局。
但是目前在这里并不合适,因为我们使用了 flex: 33.33%
,无论在什么情况下,宫格中的每个 flex 元素宽度始终是 flex 容器的 33.33% 左右,且是相邻的。毕竟现在这个很自适应,很有弹性。
既然 flex 相关的属性无法满足我们的需求,那么我们可以使用别的方式来处理。但,我们不能使用 margin
的方式来处理。一旦出现 margin
相关的属性后,那么这个 flex 元素的宫格宽度就不再是 33.33%,也就无法得到一行三列的宫格了。
.item {
/* 让每个 item 元素的宽度初始为 33.33%,其实也就是想让一行三列“均分”一下 */
flex: 33.33%;
/* 由于 item 自身有 padding,为了便于计算所以采用 border-box 的盒模型计算方式 */
box-sizing: border-box;
margin: 5px;
}
间距是有了,但是结果却不对了。
其实呢,这个时候我们完全可以利用 box-sizing
这个属性。因为 border-box
的属性值,所以当我们有 border
的时候,并不会影响 flex 元素的宽度计算结果。
.item {
/* 让每个 item 元素的宽度初始为 33.33%,其实也就是想让一行三列“均分”一下 */
flex: 33.33%;
/* 由于 item 自身有 padding,为了便于计算所以采用 border-box 的盒模型计算方式 */
box-sizing: border-box;
border: 5px solid #fff;
}
等高等宽等比的宫格
从页面布局情况来说,这样相对来说好看一点了。不过要是每个 flex 元素的宽高是相同的话,那岂不是更好。就类似现在很多 app 中的宫格排列时,都是放相同大小的 icon 图标。所以,我们也改改。
.item {
/* 让每个 item 元素的宽度初始为 33.33%,其实也就是想让一行三列“均分”一下 */
flex: 33.33%;
/* 由于 item 自身有 padding,为了便于计算所以采用 border-box 的盒模型计算方式 */
box-sizing: border-box;
border: 5px solid #fff;
position: relative;
/* 这个只是为了去掉目前元素的那些数字 */
font-size: 0;
}
.item::after {
/* 不考虑增加额外元素而使用了 ::after,故而通过 block 块级处理 */
display: block;
content: '';
position: relative;
top: 0;
left: 0;
/* 宽度等于父元素的宽度 */
width: 100%;
/* 以父元素的宽度为标准,通过 padding 方式撑开自身的高度 */
padding-top: 100%;
}
通过伪元素的方式撑开每个 flex 元素高度,其实宽高相同。这样就能够得到需要的宫格了。
但是这样看,是不是感觉宫格的行数太多,并且每个格子都太大了呢,一行也没放下几个。不要担心,我们只要简单修改一下 .item
中的 flex
值就可以了。
.item {
/* 让每个 item 元素的宽度初始为 33.33%,其实也就是想让一行三列“均分”一下 */
flex: 20%;
......
从 33.33% 转为 20%,现在我们可以得到的结果就是这样了。
好像哪里不对的样子,第二行的格子为什么会大一些呢。对了,因为现在是一行有 5 个格子,而我们只有 9 个元素,所以,第二行因为宽度弹性撑开了,而高度由于 padding-top
的关系也撑开了,最终导致第二行显得大一些。
要解决这个问题,我们是不是把第十个 item 展示出来就好了呢?不不不,完全没这个必要。我们只需要简简单单的加个 0
就可以了。
.item {
/* 让每个 item 元素的宽度初始为 33.33%,其实也就是想让一行三列“均分”一下 */
flex: 0 20%;
......
嗯。现在看起就舒服多了。
小结
宫格的布局实现其实也是简单的,关键主要在于对 flex
这个属性的把控。这个例子中用了 padding
的方式来实现等比大小缩放的元素的,该元素可作为一个父元素插入 img
,也可以直接使用 background-image
的方式插入图片。