css 一直是用来页面布局的 早期我们使用table来布局 后面又有了浮动 定位 但这些本质上都是hack模式 并且都没有垂直居中的功能 CSS3里面有了伸缩盒子 一定程度上解决了这些问题 但它更适用于一维布局 在我们实际开发中 往往是复杂的二维布局 Grid布局就是为了解决复杂布局模块而生的CSS模块
grid布局 简单来所也是网格布局 由以下属性组成
网格容器: 所以网格项加起来之和 是网格单元之父
网格单元: 相邻的列网格线和行网格线组成的网格单元 也即使最小的网格单元
网格项: 也就是网格中的一个个格子 网格单元
网格区: 任意的网格单元的组合
网格线: 横向网格线和竖直网格线
网格轨道: 相邻网格线之间的距离
父元素属性:
属性 | 说明 |
display | 设置grid布局 |
grid-template-rows | 设置网格的行数 |
grid-template-columns | 设置网格的列数 |
grid-template-areas | 网格单元重命名 |
grid-column-gap | 列网格轨道的大小 |
grid-row-gap | 行网格轨道的大小 |
grid-gap | grid-row-gap和grid-column-gap 缩写 |
justify-items | 所有的网格单元在X轴的对齐方式 |
align-items | 所有的网格单元在Y轴的对齐方式 |
place-item | X轴和Y轴对齐方式缩写 |
justify-content | 所有的网格单元在X轴的排列方式 |
align-content | 所有的网格单元在Y轴的排列方式 |
grid-auto-columns | 设置网格容器中列的尺寸 |
grid-auto-rows | 设置网格容器中行的尺寸 |
grid-auto-flow | 布局时候 控制网格的排列方向 |
// 有几个值表示有几列 单位可以是px 也可以百分比 fr表示在剩余的空间里面等比分配
grid-template-columns:100px 10% 1fr 2fr
// 这里的c表示网格单元的别名
grid-template-columns: [c1] 200px [c2] 200px [c3] 1fr [c4]
//表示创建12个大小相等的列
grid-template-columns:repeat(12 1fr)
// auto-fit 自适应 尽量用100px来填满网格
grid-template-columns: repeat(auto-fit, 100px)
//当大小小于100的时候 用最小单位100px 大于100px的时候 平均分配
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr))
justify-items 属性值
start | 网格中的左端对齐 |
center | 网格中的居中对齐 |
end | 网格中的右端对齐 |
stretch | 网格中的内容宽度占满整个空间 |
align-items 与 justify-items 属性值一样
justify-content 属性值
start | X轴上左端对齐 |
center | X轴上居中对齐 |
end | X轴上右端对齐 |
stretch | X轴上内容宽度占满整个空间 |
space-around | X轴上中间是两端的两倍 |
space-between | X轴上两端对齐 中间平分 |
space-evenly | X轴上每一列的间距相同 |
grid-auto-flow:
column | 网格从上向下排列 |
row | 网格从左向右排列 |
相关案例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.item{
border: 1px solid #ccc;
border-radius: 10px;
}
.item-column{
height: 100px;
margin-bottom: 20px;
}
.item-row{
width: 100px;
}
.item1{
grid-row: 1 / 3;
background: rgba(232, 140, 217, 0.5);
}
.item2{
grid-column: 1 / 3;
background: rgba(232, 140, 217, 0.5);
}
.column{
display: grid;
grid-template-columns: 100px 100px 1fr 1fr;
grid-column-gap: 10px;
}
.column2{
display: grid;
grid-template-columns: repeat(6, 150px);
grid-column-gap: 10px;
border: 1px solid #ccc;
padding: 10px;
align-items: center;
}
.column3{
display: grid;
grid-template-columns:150px 150px 150px;
grid-template-rows: 150px 150px 150px;
grid-column-gap: 10px;
}
.column4{
display: grid;
grid-auto-columns: 300px;
background: #2196F3;
height: 240px;
padding: 20px;
grid-column-gap: 10px;
}
.column5{
display: grid;
grid-template: auto auto / auto auto;
grid-auto-flow:column;
}
.row0{
display: grid;
place-items: center;
}
.row{
display: grid;
grid-template-rows: 100px 1fr 20%;
grid-row-gap: 10px;
}
.row2{
display: grid;
grid-template-rows: 100px 1fr 20%;
grid-template-columns: 1fr 1fr;
grid-row-gap: 10px;
justify-items: center;
}
.row3{
display: grid;
grid-template-rows: 100px 1fr 20%;
grid-template-columns: 150px 150px 150px;
grid-row-gap: 10px;
justify-content: space-around;
}
.row4{
display: grid;
grid-auto-rows:100px;
}
.row5{
display: grid;
grid-template: auto auto / auto auto;
grid-auto-flow:row;
}
</style>
</head>
<body>
<h1>竖直排列</h1>
<div class="column">
<div class="item item-column">11</div>
<div class="item item-column">22</div>
<div class="item item-column">33</div>
<div class="item item-column">44</div>
</div>
<h1>align-items</h1>
<div class="column2">
<div class="item item-column item1">11</div>
<div class="item item-column">22</div>
<div class="item item-column">33</div>
<div class="item item-column">44</div>
<div class="item item-column">55</div>
<div class="item item-column">66</div>
<div class="item item-column">77</div>
</div>
<h1>align-content</h1>
<div class="column3">
<div class="item item-column">11</div>
<div class="item item-column">22</div>
<div class="item item-column">33</div>
<div class="item item-column">44</div>
<div class="item item-column">55</div>
</div>
<h1>grid-auto-columns</h1>
<div class="column4">
<div class="item">11</div>
<div class="item">22</div>
<div class="item">33</div>
<div class="item">44</div>
</div>
<h1>grid-auto-flow</h1>
<div class="column5">
<div class="item">11</div>
<div class="item">22</div>
<div class="item">33</div>
<div class="item">44</div>
</div>
<h1>place-item</h1>
<div class="row0">
<div class="item">11</div>
<div class="item">22</div>
<div class="item">33</div>
<div class="item">44</div>
</div>
<h1>横向排列</h1>
<div class="row">
<div class="item">55</div>
<div class="item">66</div>
<div class="item">77</div>
</div>
<h1>justify-items</h1>
<div class="row2">
<div class="item item-row">11</div>
<div class="item item-row">22</div>
<div class="item item-row">33</div>
<div class="item item-row">44</div>
<div class="item item-row">55</div>
</div>
<h1>justify-content</h1>
<div class="row3">
<div class="item item2 item-row">11</div>
<div class="item">22</div>
<div class="item">33</div>
<div class="item">44</div>
<div class="item">55</div>
<div class="item">66</div>
<div class="item">77</div>
</div>
<h1>grid-auto-rows</h1>
<div class="row4">
<div class="item">11</div>
<div class="item">22</div>
<div class="item">33</div>
<div class="item">44</div>
</div>
<h1>grid-auto-flow</h1>
<div class="row5">
<div class="item">11</div>
<div class="item">22</div>
<div class="item">33</div>
<div class="item">44</div>
</div>
</body>
</html>
grid-column-start 和 grid-row-start 可以分别指定 从竖直方向 和 横向方向 从第几个网格开始排列
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#grid {
height: 200px;
width: 200px;
display: grid;
grid-gap: 10px;
grid-template: repeat(4, 1fr) / repeat(2, 1fr);
grid-auto-flow: column;
border: 1px solid red
}
#item1 {
background-color: lime;
grid-row-start: 3;
}
#item2 {
background-color: yellow;
}
#item3 {
background-color: blue;
}
#item4 {
grid-column-start: 2;
background-color: red;
}
#item5 {
background-color: aqua;
}
</style>
</head>
<body>
<div id="grid">
<div id="item1">1</div>
<div id="item2">2</div>
<div id="item3">3</div>
<div id="item4">4</div>
<div id="item5">5</div>
</div>
</body>
</html>
grid-area 可以对网格进行重命名 从而可以随意改变该网格在网格容器中的位置
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
main {
display: grid;
grid-template-columns: 10rem auto;
grid-template-rows: auto auto 1fr auto;
grid-template-areas: "header header" "title article" "nav article" "footer footer";
}
header {
grid-area: header;
background: lightblue;
}
div {
grid-area: title;
background: orange;
}
nav {
grid-area: nav;
background: pink;
}
article {
grid-area: article;
background: yellow;
}
footer {
grid-area: footer;
background: lightblue;
}
.box {
background-color: #999;
display: grid;
grid-template-columns: 100px 80% 1fr 1fr;
grid-template-rows: 200px 300px 300px;
grid-template-areas: "header header header ."
"main main . sidebar"
"footer footer footer footer"
/*名字便是元素的名字,点(.)代表的意思是空一格,这个单元格中不放内容*/
}
.a {
grid-area: header;
/*grid-area:; 是给子元素起一个名字*/
background-color: red;
}
.b {
grid-area: main;
background: blue;
}
.c {
grid-area: sidebar;
background: pink;
}
.d {
grid-area: footer;
background: black;
}
</style>
</head>
<body>
<main>
<header>This is the header</header>
<div>This is the title</div>
<nav>This is the nav</nav>
<article>
This is the article. This is the article. This is the article. This is the article.
This is the article. This is the article. This is the article. This is the article.
This is the article. This is the article. This is the article. This is the article.
This is the article. This is the article. This is the article. This is the article.
This is the article. This is the article. This is the article. This is the article.
This is the article. This is the article. This is the article. This is the article.
</article>
<footer>This is the footer</footer>
</main>
</body>
</html>
grid-row 和 grid-template 可以分别指定 在 横向网格 和 竖直网格上 起始位置到终点位置
grid-column: 1/2; 表示从第一列开始 第二例结束 占一格
grid-row: 1 / span 2; 表示从第一行开始 占两格 相当于从第一行开始 第3行结束
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.container {
display: grid;
grid-template: auto 1fr auto / auto 1fr auto;
height: 99vh;
}
.border {
border: 1px solid red;
}
/* grid-column 表示从哪一列开始 哪一列结束 */
.header,.footer{
padding: 10px;
grid-column: 1 / 4;
}
.left{
grid-column: 1/2;
}
.container1{
display: grid;
grid-template: auto auto auto/ auto auto auto;
}
.border1{
grid-row: 1 / span 2;
}
</style>
</head>
<body>
<div class="container">
<div class="border header">Header</div>
<div class="border left">Left Sidebar</div>
<div class="border main">Main Content</div>
<div class="border right">Right Sidebar</div>
<div class="border footer">Footer</div>
</div>
<!-- 在Y轴上的起终位置 -->
<div class="container1">
<div class="border border1">11</div>
<div class="border">22</div>
<div class="border">33</div>
<div class="border">44</div>
<div class="border">55</div>
<div class="border">66</div>
</div>
</body>
</html>
auto-fill 和 auto-fit的区别
grid布局有一个非常强大的功能 模式填充(repeat-to-fill)可以对剩下内容进行填充分配 也就是我们只需要关注列的数目 不用考虑在大于预期宽度或者小于宽度的时候 用js或者用媒体查询来进行自适应屏幕大小
比如 我们现在指定容器有4列 grid-template-columns: repeat(auto-fit, minmax(300px, 1fr))
当屏幕大于300*4 的时候 屏幕宽度是1500 1500-(300*4) 剩余空间是300 fit就会将剩下的空间300在平均分配给这4个容器 容器对应的宽度是 300 + 300/4 = 375
当屏幕宽度小于300*4的时候 屏幕宽度是1000 只能放下3个容器 那么第四个就会被排到下一行 然后把1000宽度 平均分配给这3个容器 以此类推 知道在手机端展示 只显示一行
auto-fill 与 auto-fit 基本是一样的 不同的是 当屏幕宽度大于所有子容器宽度之和的时候 不会将剩余的空间平均分配给子容器
案例如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.container {
display: grid;
/* 当元素宽度小于300px时候 以最小单位300px来展示 当大于300px时候 将自适应屏幕
如果改为auto-fill 当大于300px的时候 不会自适应填充剩下的空间 */
grid-template-columns: repeat(auto-fit, minmax(500px, 1fr));
height: 90vh;
}
.border {
border: 1px solid red;
}
</style>
</head>
<body>
<div class="container">
<div class="border">1</div>
<div class="border">2</div>
<div class="border">3</div>
<div class="border">4</div>
</div>
</body>
</html>