Grid网格布局 容器属性与子项属性 Grid实现自适应三栏布局
Grid 网格布局
网格布局是最强大的CSS布局方案,将网页划分成一个个网格
可以任意组合不同的网格,做出各种各样的布局
网格布局与弹性布局有一定的相似性,都可以指定容器内部多个项目的位置,
但是也存在重大区别
1.1 和flex布局的区别:
- grid容器子项是单元格,而非子元素(当然,如果子元素没有设置宽高,那么他的宽高跟随单元格,值得一提的是,子元素样式calc函数的100%也是相对于单元格而非容器元素),而flex容器的子项直接即是子元素
- Flex布局是轴线布局,只能指定"项目"针对轴线的位置,是一维布局
- grid将容器划分成行和列,产生单元格,然后指定项目所在单元格,可以看作是二维布局
1.2 基本概念
容器和项目:即容器结点和子节点
行和列:水平区域/垂直区域
单元格:行和列的交叉区域,n行m列会产生n×m个单元格
网格线:划分网格的线,水平网格线和垂直网格线分别决定了行和列,n行有n+1根网格线
1.3 容器属性
- Grid项目指子节点,不包含孙子节点,Grid子项(单元格)默认都是块级元素
- 和flex布局一样,Grid布局不影响容器之外的元素
- 设置Grid布局以后,容器子项的float、display等属性失效
- 指定网格布局:display:grid
1.3.1 指定块级容器和行内容器
display:grid
display:inline-grid
1.3.2 列宽和行高
容器指定了网格布局以后,接着就要划分行和列
grid-template-columns: 每列列宽, 是设置子项(单元格)的属性,而不是子元素宽高,但是可以用calc函数相对于父元素做子元素计算
grid-template-rows:每行行高
有时候重复的值很多,写起来很麻烦,这时,可以使用repeat函数,简化重复的值
简写:
grid-template-columns:repeat(3, 33, 33%) 三列均分布局
grid-template-rows:repeat(3, 33.33%) 每行行高为33.33%
<style>
.wrapper {
height: 500px;
width: 600px;
display: grid;
background: lightseagreen;
/* 定义列宽。指的是子项(单元格)的宽度,而非子元素的宽度*/
grid-template-columns: repeat(3, 200px);
/* 定义每行行高 */
grid-template-rows: 100px 100px 100px;
/* repeat(3,200px) equals to 200px 200px 200px */
}
.child {
width: 100px;
height: 100px;
background: lightsalmon;
font-size: 12px;
}
</style>
<body>
<div class="wrapper">
<div class="child"><span>grandchild</span></div>
<div class="child"><span>grandchild</span></div>
<div class="child"><span>grandchild</span></div>
</div>
</body>
1.3.3 自动填充 auto-fill关键字
有时候,单元格大小固定,但是容器的大小不固定,可以用这个属性包含尽可能多的列
即:不指定容器的列数,只指定容器的列宽,具体一行多少列数,由容器宽来做自适应,尽可能容纳更多的列数
<style>
.container{
width: 430px;
height: 500px;
background: lightseagreen;
display: grid;
grid-template-columns: repeat(auto-fill,100px);
grid-template-rows: repeat(3 200px);
gap: 10px;
}
.item{
width: 100px;
height: 100px;
background: lightsalmon;
}
</style>
<body>
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</body>
1.3.4 比例关系 fr关键字
有时候为了方便表示比例关系,grid布局提供了fr关键字(fraction, 片段)
如果两列的宽分别为1fr 和 2fr 那么前者是后者的两倍
如果全是1fr, 表示均分
如果是100px 1fr 2fr, 则表示第一列100px, 剩下均分,但是第二列是第三列的1/2
<style>
.container{
width: 530px;
height: 500px;
background: lightseagreen;
display: grid;
/* 4个单元格均分容器宽 */
/* grid-template-columns: repeat(4,1fr); */
/* 第一列宽200px,剩下3列均分剩余容器宽 */
grid-template-columns: 200px repeat(3,1fr);
grid-template-rows: repeat(3 200px);
gap: 10px;
}
.item{
/* 这个100%是相对于单元格,而非容器 */
width: calc(100% - 10px);
height: 100px;
background: lightsalmon;
}
</style>
<body>
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</body>
1.3.5 长度范围 minmax
minmax指定长度范围,如指定第一列列宽不小于100px不大于200px
<! DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
.container{
width: 530px;
height: 500px;
background: lightseagreen;
display: grid;
/* 指定宽度范围,实际宽度190px,按最大情况处理,剩下fr均分 */
grid-template-columns: minmax(100px,200px) repeat(3,1fr);
grid-template-rows: repeat(3 200px);
gap: 10px;
}
.item{
/* 这个100%是相对于单元格,而非容器 */
width: calc(100% - 10px);
height: 100px;
background: lightsalmon;
}
</style>
<body>
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</body>
</html>
1.3.6 Grid实现两栏布局和三栏自适应布局
三栏布局,中间自适应, 将左右两栏写死,中间设置1fr自动分配即可
<style>
body,
html {
width: 100%;
height: 100%;
/* 去掉滚动条 */
margin: 0;
}
.container {
width: 100%;
height: 100%;
background: lightseagreen;
display: grid;
/* 两栏布局 */
/* grid-template-columns: 70% 30%; */
/* 三栏布局,中间自适应,将左右两栏写死,中间设置1fr自适应分配即可 */
grid-template-columns: 100px 1fr 200px;
/*不写默认是100%,子元素默认撑满单元格高度 */
/* grid-template-rows: 100px; */
}
.left {
background: skyblue;
}
.right {
background: rebeccapurple;
}
.con {
background: orange;
}
</style>
<body>
<div class="container">
<div class="left"></div>
<div class="con"></div>
<div class="right"></div>
</div>
</body>
1.3.7 grid间隔
grid-row-gap:设置行间隔
grid-column-gap:设置列间隔
grid-gap: 设置行间隔于列间隔
<! DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
.container{
width: 530px;
height: 500px;
background: lightseagreen;
display: grid;
grid-template-columns: repeat(3,1fr);
gap: 10px 10px;
}
.item{
background: lightsalmon;
}
</style>
<body>
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</body>
</html>
1.3.8 grid-auto-flow属性
通过grid-template-columns和grid-template-rows设置好行列,确定好单元格之后
可以用grid-auto-flow来决定子元素是先填满行还是先填满列
<! DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
.container {
width: 930px;
height: 900px;
background: lightseagreen;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
gap: 10px 10px;
/* 先行后列,默认,即子元素先填满行 */
/* grid-auto-flow: row; */
/* 先列后行,即子元素先填满第一列 */
grid-auto-flow: column;
}
.item {
width: 50px;
height: 50px;
background: lightsalmon;
}
</style>
<body>
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
</body>
</html>
1.3.9 justify-items align-items justify-content align-content
justify-items align-items
设置的是单元格内容相对于单元格的水平/垂直位置
start:对齐单元格的起始边缘
end:对齐单元格的结束边缘
center:单元格内部居中
stretch:拉伸,占满单元格的整个宽度(默认值)
jusityfy-content align-content
设置的是整个内容区域在Grid容器中的位置
justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
align-content: start | end | center | stretch | space-around | space-between | space-evenly;
<! DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
.container {
width: 930px;
height: 900px;
background: lightseagreen;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
gap: 10px 10px;
/* justify-items/align-items设置单元格内容的水平/垂直位置 */
justify-items: center;
align-items: center;
}
.item {
width: 50px;
height: 50px;
background: lightsalmon;
}
</style>
<body>
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
</body>
</html>
1.4 子项属性
1.4.1 grid-columns-start/end 指定某个子项起止哪根网格线
<! DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
.container {
width: 930px;
height: 900px;
background: lightseagreen;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
gap: 10px 10px;
/* 先行后列,默认,即子元素先填满行 */
/* grid-auto-flow: row; */
/* 先列后行,即子元素先填满第一列 */
/* grid-auto-flow: column; */
}
.item {
/* width: 100%; */
/* height: 100%; */
width: 50px;
height: 50px;
background: lightsalmon;
}
/* grid-column-start/end 第一个子元素起始于垂直第一根网格线,终止于垂直第三根网格线,共占据两个单元格 */
.item:nth-child(1){
width: 100%;
background: red;
grid-column-start: 1;
grid-column-end: 3;
}
</style>
<body>
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
</body>
</html>
1.4.2 grid-area 指定某个元素位于哪个区域
如以下位于区域e
.container {
width: 930px;
height: 900px;
background: lightseagreen;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
gap: 10px 10px;
/* justify-items/align-items设置单元格内容的水平/垂直位置 */
/* justify-items: center; */
/* align-items: center; */
/* justify-content/align-content设置的是内容区域在整个Grid容器中的位置 */
/* justify-content: space-between ; */
grid-template-areas: 'a b c'
'd e f'
'g h i';
}
.item {
/* width: 50px; */
/* height: 50px; */
background: lightsalmon;
}
.item:nth-child(1) {
grid-area: e;
}
1.4.3 jusity-slef align-self
设置单元格内容的水平/垂直位置,jusity-slef、align-self跟justify-items、align-self的用法效果相同,却别在于,前者是子项属性,只作用于某一个单元格,后者是容器属性,作用于所有单元格
如以下案例只会设置第一个子项水平在单元格内水平垂直居中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
.container {
width: 930px;
height: 900px;
background: lightseagreen;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
gap: 10px 10px;
/* justify-items/align-items设置所有单元格内容的水平/垂直位置 */
/* justify-items: center; */
/* align-items: center; */
/* justify-content/align-content设置的是内容区域在整个Grid容器中的位置 */
/* justify-content: space-between ; */
}
.item {
width: 100px;
height: 100px;
background: lightsalmon;
}
.item:nth-child(1) {
/* 设置的是某个子元素在单元格内容中的水平/垂直位置 */
justify-self: center;
align-self: center;
}
</style>
<body>
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
</div>
</body>
</html>
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性