网格布局的前端布局
Grid布局
优点
二维布局,可以同时设定x轴与y轴
缺点
兼容性差一点,还有就是,复杂
基本语法
/* html */
<div class="container">
<div class="item item-1"></div>
<div class="item item-2"></div>
<div class="item item-3"></div>
</div>
/* css */
.container {
display: grid;
}
基本概念
先了解一下基本名词:
- 网格容器 (container)
- 网格项 (item)
- 网格线 (Grid布局可以想象成一个表格,构成表格的线就是网格线)
- 网格轨道 (表格的一个横排或者一个竖排就是网格轨道)
- 网格单元格 (就是表格的一个格子)
- 网格区域 (相邻组团的格子)
网格容器的属性(用表格来阐释)
display
这个就不用多说,两种格式display: grid | inline-grid;
grid-template-columns/grid-template-rows
td
的宽度/高度,举例
.container {
grid-template-columns: 40px 50px auto 50px 40px;
grid-template-rows: 25% 100px auto;
}
第一个属性定义了5个值,那么就有5列,第二个属性定义了3个值,就有3行
此外,还有一个新的单位fr
grid-template-columns: 1fr 50px 1fr 1fr;
这个例子中,就是总宽度减去50px,然后剩余空间平分
当属性重复的时候可以用repeat()
grid-template-columns: repeat(4, 1fr);
// 相当于
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-template-areas
这个属性用来定义网格区域,直接上代码
.item-a {
grid-area: header;
}
.item-b {
grid-area: main;
}
.item-c {
grid-area: sidebar;
}
.item-d {
grid-area: footer;
}
.container {
grid-template-columns: 50px 50px 50px 50px;
grid-tempalte-rows: auto;
grid-tempalte-areas:
"header header header header"
"main main . sidebar"
"footer footer footer footer";
}
上面的代码定义了一个3行4列的表格,然后给item-a/b/c/d
起了个名字,这些个名字就能当做占位符去占位置,header、footer
就整整占了一行
. 代表空区域,位置是空的
这不,圣杯布局
出来了
grid-column-gap/grid-row-gap
定义列,行之间的间距,两个属性有一个合并属性grid-gap
justify-items
定义内容在td
中的横向表现方式,就相当于text-align
- start ====== left
- center ====== center
- end ====== right
- stretch 把td宽度填充满
align-items
定义内容在td
中的纵向表现方式,相当于vertical-align
- start ====== top
- center ====== center
- end ====== bottom
- stretch 把td高度填充满
place-items
align-items
和 justify-items
的合并属性
justify-content/align-content
这个属性用来定义整体网格项相当于网格容器的横向/纵向位置,网格容器太大了,网格项用px
之类的单位固定了宽高,所有的网格项加起来填不满网格容器
- start 左/上
- end 右/下
- center 中
- stretch 每个网格项横向/纵向等比放大至填充满td
- space-around 每一列/行之间放置一个均匀的空间,左右/上下两端放置一半的空间
- space-between 每一列/行之间放置一个均匀的空间,左右/上下两端没有空间
- space-evenly 每一列/行之间放置一个均匀的空间,左右/上下两端放置一个均匀的空间
place-content
justify-content
和align-content
合并属性
grid-auto-columns / grid-auto-rows
定义新生成的网格轨道的大小,比如一个页面默认数据为9个3行3列,
grid-tempalte-columns: 1fr 1fr 1fr;
grid-tempalte-rows: 150px 150px 150px;
但是当有新的网格项出现时候,要想跟之前的网格项保持一致,则必须要设置
ggrid-auto-columns: 1fr 1fr 1fr;
grid-auto-rows: 150px 150px 150px;
grid-auto-flow
自动放置算法,当有一些没有明确指定位置的网格项,会自动放置这些网络,属性值:
- row 自动布局算法一行一行的来填充,根据需求会添加新行
- column 自动布局算法一列一列的来填充,根据需求会添加新列
- dense 告诉自动布局算法在稍后出现较小的网格项时,尝试填充网格中较早的空缺
dense 会更改可视顺序,并到处出现乱序,对访问行不利
定义一个5列2行的表格,将item-a
和item-e
的位置指定,剩下的b.c.d
则交给自动布局算法
grid-auto-flow:row
grid-auto-flow:column
网格项属性
float
,display:inline-block
,display:table-cell
,vertical-align
和column-*
属性对网格项无效
grid-column / grid-row
用来指定网格项的位置,如果值是单个值m
,则表示该网格项在m行/列,如果值是m/n
形式,表示从第m个网格线到第n个网格线,如果值是m/span n
,表示从第m个网格线开始横跨n个列/行
.item-c {
grid-column: 3 / span 2;
grid-row: 3 / 4;
}
同时网格还可以重叠,用z-index
控制顺序就可以了
grid-area
给自己起个别名,上面已经出现过
justify-self
跟网格容器的justify-items
一个意思
align-self
跟网格容器的align-items
一个意思
place-self
justify-self
和align-self
的合并属性
grid实现瀑布流
首先看dom结构
<div class="container" id="app">
</div>
不着急,上面就是一个容器,主体内容还得借助JS才行,纯CSS实现的瀑布流有点差强人意,下面看CSS
.container {
width: 600px;
margin: 50px auto;
border: 1px solid #ccc;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-column-gap: 10px;
}
然后用JS操作插入元素
let app = document.querySelector('#app');
let html = '';
let arr = [50, 100, 150];
let color = ['red', 'blue', 'yellow'];
for (let i = 0; i < 15; i++) {
let h = Math.floor(Math.random() * 3);
html += `<div style="height: ${arr[h]}px;background-color: ${color[h]};grid-row:auto/span ${h + 1}">${i}</div>`
}
app.innerHTML = html;
上面代码中的关键是grid-row:auto/span ${h + 1}
,这个属性是定义当前网格项在整个网格中的位置,它是grid-row-start
和grid-row-end
的组合属性。
用表格来说明
首先要理解其中的span
,span
的意思就是一个单元格,相当于一个td
,那这个td的宽度和高度是由它所在列和所在行的最大宽度和最大高度决定的,grid网格也是如此。
但是假如每个网各项都设定了grid-row
,单元格的宽度与高度就由设定span 1
的网格项的宽高度来决定了,比如上面的例子中,grid-row:auto/span 1
对应的网格项的高度是50px
,那么一个单元格的高度就是50px
,而grid-row-start:auto;
会让网格项自动去寻找缺口,这样,瀑布流就OK了
注意
- 不能设置
grid-row-gap
,因为一个单元格是50px
,如果单元格的间隙是10px
,那么一个高度为100px
的网格项仅会占据下面一个单元格的40px
,而它下面的网格项的起始位置只会对准网格线,所以它俩之间的距离就变成了20px
,这样就不好看了 - 例子中单元格的高度设置成了
50px
,也可以更小,比如10px
,这样高度就会更灵活一些 - 复制上面的例子,本地运行在谷歌浏览器中打开开发者工具你就会看到
网格