grid 布局
目前 web 开发主流的布局方式为:block 和 flex,它们都是一维的布局,定义了元素在一条线上的排布方式,而新增的 grid 布局是二维的布局方式。
在火狐浏览器下,可以通过几行代码实现瀑布流布局,但是兼容性不好
css
.container {
display: grid;
grid-template-columns: repeat(4, 1fr);
/* 兼容性不好 */
grid-template-rows: masonry;
grid-gap: 10px;
}
.container {
display: grid;
grid-template-columns: repeat(4, 1fr);
/* 兼容性不好 */
grid-template-rows: masonry;
grid-gap: 10px;
}
而在 Chrome 浏览器上可以根据别的属性实现,先了解一下 grid 的具体用法
未定义格子占位时的表现
css
.container-1 {
background-color: #eee;
width: 500px;
height: 500px;
display: grid;
grid-template-rows: 100px 100px 100px 100px 100px;
grid-template-columns: 100px 100px 100px 100px 100px;
.cell-1 {
background-color: blue;
}
.cell-2 {
background-color: yellow;
}
}
.container-1 {
background-color: #eee;
width: 500px;
height: 500px;
display: grid;
grid-template-rows: 100px 100px 100px 100px 100px;
grid-template-columns: 100px 100px 100px 100px 100px;
.cell-1 {
background-color: blue;
}
.cell-2 {
background-color: yellow;
}
}
定义格子占位后
css
.container-2 {
background-color: #eee;
width: 500px;
height: 500px;
display: grid;
grid-template-rows: 100px 100px 100px 100px 100px;
grid-template-columns: 100px 100px 100px 100px 100px;
.cell-1 {
background-color: blue;
grid-row: 1 / 3;
/* 占据1-3行 */
grid-column: 1 / 3;
/* 占据1-3列 */
/* 可以简写为: grid-area: 1 / 1 / 3 / 3; */
}
.cell-2 {
background-color: yellow;
grid-row: 2 / 4;
/* 占据2-4行 */
grid-column: 3 / 6;
/* 占据3-6列 */
}
}
.container-2 {
background-color: #eee;
width: 500px;
height: 500px;
display: grid;
grid-template-rows: 100px 100px 100px 100px 100px;
grid-template-columns: 100px 100px 100px 100px 100px;
.cell-1 {
background-color: blue;
grid-row: 1 / 3;
/* 占据1-3行 */
grid-column: 1 / 3;
/* 占据1-3列 */
/* 可以简写为: grid-area: 1 / 1 / 3 / 3; */
}
.cell-2 {
background-color: yellow;
grid-row: 2 / 4;
/* 占据2-4行 */
grid-column: 3 / 6;
/* 占据3-6列 */
}
}
使用 span 关键字延伸
css
.cell-1 {
background-color: blue;
grid-row: 1 / span 3;
/* 占据1延伸3行 */
grid-column: 1 / span 3;
/* 占据1延伸3列 */
/* 可以简写为: grid-area: 1 / 1 / 3 / 3; */
}
.cell-1 {
background-color: blue;
grid-row: 1 / span 3;
/* 占据1延伸3行 */
grid-column: 1 / span 3;
/* 占据1延伸3列 */
/* 可以简写为: grid-area: 1 / 1 / 3 / 3; */
}
grid line 命名
less
.container-4 {
background-color: #eee;
width: 540px;
height: 540px;
display: grid;
grid-template-rows: [X1] 100px [X2] 100px [X3] 100px [X4] 100px [X5] 100px;
grid-template-columns: [Y1] 100px [Y2] 100px [Y3] 100px [Y4] 100px [Y5] 100px;
grid-template-areas:
'header header header header header'
'nav main main main main'
'nav main main main main'
'nav main main main main'
'. footer footer footer .';
row-gap: 10px;
column-gap: 10px;
.header {
background-color: blue;
grid-area: header;
}
.nav {
background-color: yellow;
grid-area: nav;
}
.main {
background-color: orange;
grid-area: main;
}
.footer {
background-color: black;
grid-area: footer;
}
}
.container-4 {
background-color: #eee;
width: 540px;
height: 540px;
display: grid;
grid-template-rows: [X1] 100px [X2] 100px [X3] 100px [X4] 100px [X5] 100px;
grid-template-columns: [Y1] 100px [Y2] 100px [Y3] 100px [Y4] 100px [Y5] 100px;
grid-template-areas:
'header header header header header'
'nav main main main main'
'nav main main main main'
'nav main main main main'
'. footer footer footer .';
row-gap: 10px;
column-gap: 10px;
.header {
background-color: blue;
grid-area: header;
}
.nav {
background-color: yellow;
grid-area: nav;
}
.main {
background-color: orange;
grid-area: main;
}
.footer {
background-color: black;
grid-area: footer;
}
}
fr 和 repeat
上述例子可以进行如下优化
css
.container-4 {
...
grid-template-rows: 3fr 1fr 1fr 1fr 1fr;
grid-template-columns: 3fr 1fr 1fr 1fr 1fr;
}
.container-4 {
...
grid-template-rows: 3fr 1fr 1fr 1fr 1fr;
grid-template-columns: 3fr 1fr 1fr 1fr 1fr;
}
表示行列空间按容器进行等分,增加这个数字则增加相应的权重。
而对于重复性的书写,可以通过 repeat 来简写
repeat 的第一个参数为重复次数,第二个参数为重复的内容
上述代码可以改造为
css
.container-4 {
...
grid-template-rows: 3fr repeat(4, 1fr);
grid-template-columns: 3fr repeat(4, 1fr);
}
.container-4 {
...
grid-template-rows: 3fr repeat(4, 1fr);
grid-template-columns: 3fr repeat(4, 1fr);
}
瀑布流实现
需要再引入 2 个概念
css
.container {
display: grid;
grid-auto-rows: minmax(1px, 1px);
grid-template-columns: repeat(3, 1fr);
}
.container {
display: grid;
grid-auto-rows: minmax(1px, 1px);
grid-template-columns: repeat(3, 1fr);
}
grid-auto-rows 表示将行按 1px 为单位进行自动等分
而子容器需要指定占据的行数,这个需要渲染后通过 DOM 操作计算出来
vue
<template>
<div class="container">
<div
v-for="let item in list"
:style="`grid-row-end: span ${item.height + 8}; height: ${
item.height
}px;`"
></div>
</div>
</template>
<template>
<div class="container">
<div
v-for="let item in list"
:style="`grid-row-end: span ${item.height + 8}; height: ${
item.height
}px;`"
></div>
</div>
</template>