什么是网格布局?
是一种强大的CSS布局方案,它将网页划分成一个个网格,可以任意组合的网格(类似excel)
grid
grid
是一个 CSS 简写属性,可以用来设置以下属性:
显式网格属性 grid-template-rows、grid-template-columns 和 grid-template-areas,
隐式网格属性 grid-auto-rows、grid-auto-columns 和 grid-auto-flow, 间距属性 grid-column-gap (en-US) 和 grid-row-gap (en-US)。
容器和项目
采用网格布局的区域,称为“ 容器 ”,容器内部的采用网格定位的子元素称为” 项目 “
我们通过在元素上声明 display:grid
或 display:inline-grid
来创建一个网格容器。一旦我们这样做,这个元素的所有直系子元素将成为网格元素。
-
grid
转换为块级元素网格
-
inline-gird
转换为行内块元素网格
语法:
.wrapper {
/* 转换 网格 布局 */
display:grid;
}
<div class="wrapper">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
一旦给wrapper 设置成 gird 布局,上面的代码中,wrapper 就是容器,item就是项目
定义列和行
语法:
grid-template-columns: 用来指定列的宽度;
grid-template-rows: 用来指定行的高度;
下面的代码就是定义一个三行三列的网格布局
.main {
width: 600px;
height: 600px;
border: 1px solid red;
display: grid;
/* 定义每行的宽度 定义几个就会有几行 */
grid-template-rows: 200px 200px 200px;
grid-template-columns: 200px 200px 200px;
};
<div class="main">
<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>
-
可以是具体的数值
-
也可以百分比
-
还可以是 fr 关键字
-
还可以是 auto
.main {
grid-template-rows:100px 100px 100px;
grid-template-rows: 33.33% 33.33% 33.33%;
/* 关键字 fr 中间占了1的2倍 占了两边各一半 一样的话都是 1fr 就行*/
grid-template-columns: 1fr 2fr 1fr;
/* auto 自动占满剩下的空间 */
grid-template-columns: 100px auto 100px;
}
可以用fr
单元 等分网格容器剩余可用空间来设置 网格轨道(Grid Track) 的大小 。例如,下面的代码会将每个网格项设置为网格容器宽度的三分之一:
.container {
grid-template-columns: 1fr 1fr 1fr;
}
剩余可用空间是除去所有非灵活网格项 之后 计算得到的。下面例子中,可用空间总量减去 50px 后再3等分 即 fr 单元的值 :
.container {
grid-template-columns: 1fr 50px 1fr 1fr;
}
repeat 函数
/*
第一个参数: 代表的是重复的次数
第二个参数: 代表的是列的宽度或者行的高度
*/
grid-template-columns: repeat(3,200px);
grid-template-rows: repeat(3,200px);
把某个值重复n次
/* 重复模式:
第一个参数: 代表的是重复的次数
第二个参数: 模式
为 50 100 50 100
*/
grid-template-columns: repeat(2,50px 100px);
网格复合属性
grid-template
是 grid-template-areas
, grid-template-rows
和 grid-template-columns
三个属性的简写,用以定义网格中的 分区、行和列 。
取值:
/* 网格复合属性:
第一个参数是列 代表列有2个网格
第二个参数是行 代表行有4个网格
后面括号数值是大小 */
grid-template: repeat(2, 1fr) / repeat(4, 1fr);
none:将 grid-template-rows , grid-template-columns , grid-template-areas 三个属性设置为关键字 none,意味着没有明确的网格,没有命名的网格区域。行 和 列 将隐式生成, 他们的大小将由 grid-auto-rows 和 grid-auto-columns 属性决定。
/* Keyword value */
grid-template: none;
gap (grid-gap) 网格间隙
column-gap(grid-coumn-gap)
CSS column-gap
属性用来设置元素列之间的间隔(gutter)大小。
用来控制左右网格间隙
语法:
column-gap: 数值;
/* 设置列与列之间的距离 */
/* grid-column-gap: 30px; */
row-gap (grid-row-gap)
row-gap
该 CSS 属性用来设置行元素之间的间隙(gutter)大小。
用来控制上下网格间隙
语法:
row-gap: 值;
/* 设置行与行之间的距离 */
/* grid-row-gap: 30px; */
网格间隙复合属性
CSS gap
属性是用来设置网格行与列之间的间隙(gutters),该属性是 row-gap 和 column-gap 的简写形式。
用来控制上下左右网格间隙 可以简写为 gap
语法:
/* 网格 距离复合属性
第一个参数是行 行与行之间距离 上下
第二个参数是列 列于列之间距离 左右
*/
gap: 20px 30px;
隐式和显示网格
当我们创建上文中网格例子的时候,我们用 grid-template-columns
属性定义了自己的列轨道,但是却让网格按所需的内容创建行,这些行会被创建在隐式网格中。显式网格包含了你在 grid-template-columns
和 grid-template-rows
属性中定义的行和列。如果你在网格定义之外又放了一些东西,或者因为内容的数量而需要的更多网格轨道的时候,网格将会在隐式网格中创建行和列。按照默认,这些轨道将自动定义尺寸,所以会根据它里面的内容改变尺寸。
你也可以在隐式网格中用 grid-auto-rows
和 grid-auto-columns
属性来定义一个设置大小尺寸的轨道。
section {
width: 700px;
height: 400px;
display: grid;
grid-template-columns: repeat(3,1fr);
grid-auto-rows: .7fr .2fr;
/* 如果1个值代表全部统一行高 如果两个值代表 第一个代表奇数 第二个代表偶数 */
background-color: aqua;
}
div:nth-child(2n+1) {
background-color: pink;
}
div:nth-child(2n+2) {
background-color: orchid;
}
<section>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
</section>
轨道大小和minmax()
在设置一个显式的网格或者定义自动创建的行和列的大小的时候,我们也许想给网格一个最小的尺寸,确保他们能扩大到容纳他里面添加的内容。
body {
font-size: 2rem;
color: white;
text-align: center;
}
div:nth-child(odd) {
background-color: #21BBD4;
}
div:nth-child(even) {
background-color: #2A737F;
}
.grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 2px;
/* 规定高度为50px 如果内容多的话就会超出 */
/* grid-auto-rows: 50px; */
/* 最小为50px 最大为auto 如果内容多的话就会跟随内容放大 */
grid-auto-rows: minmax(50px,auto);
grid-template-columns: minmax(300px,500px) 1fr 1fr;
}
<main class="grid">
<div>1 hello <br> world!</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
<div>11</div>
<div>12</div>
</main>
设置单元格内容的对齐方式
justify-items:控制单元格内容在水平方向的上对齐方式:start|center|end|stretch
align-items:控制单元格内容在垂直方向上的对齐方式:start|centerjend|stretch
-
start:对齐单元格的起始边缘。
-
end:对齐单元格的结束边缘。
-
center:单元格内部居中。
-
stretch:拉伸,占满单元格的整个宽度(默认值)。
place-items:'align-items' 'justify-items' 的简写。
例如:
*{
margin: 0;
padding: 0;
}
.contain
{
width: 600px;
height: 600px;
border: 1px solid red;
display: grid;
grid-template-rows: repeat(3,200px);
grid-template-columns: repeat(3,200px);
margin: 100px auto;
/* 控制项目在单元格中的水平对齐方式 */
/* justify-items: center; */
/* 控制项目在单元格中的垂直对齐方式 */
/* start 顶部对齐 end 底部对齐 center 中心对齐 */
/* align-items: center; */
/* 位置复合属性 */
/* 第一个代表垂直 */
/* 第二个数值代表水平 */
/* place-items: center center; */
justify-content: center;
}
.item
{
width: 50px;
height: 50px;
line-height: 50px;
text-align: center;
}
.item:nth-child(even)
{
background: pink;
}
.item:nth-child(odd)
{
background: gold;
}
<div class="contain">
<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>
整个个内容区域在容器中的对齐方式
-
justify-content:控制整个内容区域在容器中的水平对齐方式
-
align-content:控制整个内容区域在垂直方向上的对齐方式
-
place-content:‘align-content’ ‘justify-content’的简写
对齐方式:
start | end | center| space-around| space-between|space-evenly|stretch;
例如:
*{
margin: 0;
padding: 0;
}
.contain
{
width: 600px;
height: 600px;
border: 1px solid red;
display: grid;
grid-template-rows: repeat(3,100px);
grid-template-columns: repeat(3,100px);
margin: 100px auto;
/* 控制内容在单元格中的水平对齐方式 */
justify-content: center;
/* 控制内容在单元格中的水平对齐方式 */
align-content: center;
/* 复合属性 */
/* 第一个值垂直 */
/* 第二个值水平 */
place-content: center center;
}
.item
{
width: 100px;
height: 100px;
line-height: 100px;
text-align: center;
}
.item:nth-child(even)
{
background: pink;
}
.item:nth-child(odd)
{
background: gold;
}
<div class="contain">
<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>
给网格布局指定区域
-
grid-template-areas
网格布局允许指定“区域”(area),一个区域由单个或多个单元格组成。grid-template-areas属性用于定义区域。
一列有几个项目名字,就是这个网格就有几列,也就是一行有几个项目名字,就是这个网格就有几行。
- grid-area
需要给里面的项目设置名字,在容器里用名字控制项目
如果一个项目想占据两个或多个网格那就弄成一样的名字,这个区域就是这个项目的了。
grid-template-areas:"a a c"
"d d f"
"g h i";
例如:
#page {
display: grid;
width: 100%;
height: 300px;
grid-template:
"head head head"
"nav main div"
"nav foot div"
"son son son";
gap: 5px 20px;
grid-auto-columns: .3fr 4fr .3fr;
/* row-gap: 5px;
column-gap: 10px; */
}
header {
background-color: lime;
grid-area: head;
}
nav {
background-color: lightblue;
grid-area: nav;
}
main {
background-color: yellow;
grid-area: main;
}
div {
background-color: yellowgreen;
grid-area: div;
}
footer {
background-color: red;
grid-area: foot;
}
.box {
background-color: rgb(0, 225, 255);
grid-area: son;
}
<section id="page">
<header>Header</header>
<nav>Navigation</nav>
<div>Div Right</div>
<main>Main area</main>
<footer>Footer</footer>
<span class="box">footer box</span>
</section>
网格线
除了可以 grid-template-areas 名字来控制容器里的项目,还可以以边框线位置来决定。
自由设置项目的具体位置,我们可以通过此项目的起始边框线来决定
-
template-row-start
-
template-row-end
-
template-column-start
-
template-column-end
应该注意的是,当我们定义网格时,我们定义的是网格轨道,而不是网格线。Grid 会为我们创建编号的网格线来让我们来定位每一个网格元素。例如下面这个三列两行的网格中,就拥有四条纵向的网格线。
网格线的编号顺序取决于文章的书写模式。在从左至右书写的语言中,编号为 1 的网格线位于最左边。在从右至左书写的语言中,编号为 1 的网格线位于最右边。
例如:
把前两个元素放到了我们的三列网格中。从左至右,第一个元素从列线 1 开始,延伸至列线 4,也就是我们这个例子中最右边的列线。并从行线 1 延伸到行线 3,占据了两个行轨道。
第二个元素从列线 1 开始,延伸了一个轨道。因为这是默认行为,所以我不用指定结束线。并且它从行线 3 到行线 5,跨越了两个行轨道。剩下的元素会自动放到网格剩余的空间中。
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 100px;
background-color: aqua;
}
.box1 {
grid-column-start: 1;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 3;
}
.box2 {
grid-column-start: 1;
grid-row-start: 3;
grid-row-end: 5;
}
.wrapper>div{
background-color: var(--bg);
}
<div class="wrapper">
<div class="box1" style="--bg:blue">One</div>
<div class="box2" style="--bg:pink">Two</div>
<div class="box3" style="--bg:yellow">Three</div>
<div class="box4" style="--bg:orange">Four</div>
<div class="box5" style="--bg:yellowgreen">Five</div>
</div>
复合属性
grid-area
第一个值代表 grid-row-start 第二个值代表 grid-column-start
第三个值代表 grid-row-end 第四个值代表 grid-column-end
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 100px;
background-color: aqua;
}
.box1 {
/* grid-column-start: 1;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 3; */
grid-area: 1/1/3/4;
}
.box2 {
/* grid-column-start: 1;
grid-row-start: 3;
grid-row-end: 5; */
grid-area: 3/1/5/-3;
}
.wrapper>div{
background-color: var(--bg);
}
使用 z-index 控制层级
多个网格项目可以占用同一个网格单位。如果我们回到之前根据网格线编号放置网格项目的话,我们可以更改此项来使两个网格项目重叠。
例如:
我们可以在网格项目发生重叠时使用 z-index
属性控制重叠的顺序——就像放置网格项目一样。如果我们给 box2
设定一个高于 box1
的 z-index
值的话,box2
将会显示在 box1 的上方。
.wrapper {
text-align: center;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 100px;
background-color: aqua;
}
.box1 {
grid-area: 1/1/3/4;
}
.box2 {
grid-area: 2/1/5/-3;
z-index: 2;
}
.wrapper>div {
background-color: var(--bg);
}
<div class="wrapper">
<div class="box1" style="--bg:blue">One</div>
<div class="box2" style="--bg:pink">Two</div>
<div class="box3" style="--bg:yellow">Three</div>
<div class="box4" style="--bg:orange">Four</div>
<div class="box5" style="--bg:yellowgreen">Five</div>
</div>
案例:
CSS
body {
font-size: 0.8rem;
padding: 2rem;
}
h2 {
margin-bottom: 0;
}
p {
margin-top: 0;
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
.parent {
display: grid;
grid-template-columns: 20ch 1fr calc(20ch + 1rem) 1fr 1rem minmax(15ch, 30ch);
grid-template-rows: 25vh 20vh 10vh 15vh 15vh;
grid-column-gap: 0px;
grid-row-gap: 0px;
}
.div1 {
grid-area: 1 / 1 / 4 / 3;
}
.div2 {
grid-area: 4 / 1 / 5 / 2;
}
.div3 {
grid-area: 3 / 2 / 6 / 4;
border: 0.5rem solid white;
z-index: 1;
}
.div4 {
grid-area: 5 / 1 / 6 / 2;
}
.div5 {
grid-area: 2 / 3 / 4 / 5;
padding-left: 1rem;
}
.div6 {
grid-area: 1 / 3 / 2 / 4;
padding-left: 1rem;
align-self: end;
}
.div7 {
grid-area: 2 / 6 / 6 / 7;
}
HTML
<div class="parent">
<div class="div1">
<img src="../img/蓝天.jpg" alt="">
</div>
<div class="div2">
<h2>place</h2>
<p>Proin id dignissim lectus, vitae hendrerit mi.</p>
</div>
<div class="div3">
<img src="../img/山.jpg" alt="">
</div>
<div class="div4">
<h2>place</h2>
<p>Proin id dignissim lectus, vitae hendrerit mi.</p>
</div>
<div class="div5">
<img src="../img/雪山.jpg" alt="">
</div>
<div class="div6">
<h2>place</h2>
<p>Proin id dignissim lectus, vitae hendrerit mi.</p>
</div>
<div class="div7">
Proin id dignissim lectus, vitae hendrerit mi. Sed egestas wst turpis,risus sit amet sem malesuada loboortis.Fuusce vestibulum, purus vitae euismod lacinia, nunc odio maximus metus, eususcipit ex est sed nunc. Aliquam vel diam sit amet quam laoreet vehicula. Etiam tortor lectus , tempor quis luctus eu, tristique eget auris. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
<br><br>
Nullam aliquam mollis lorem eu feugiat. Vivamus eleifend diam vel libero
pharetra vehicula. Fusce sit amet enim elit. Suspendisse et fringilla ligula. Pellentesque ac quam sapien. Duis
tincidunt mattis ipsum, ut mollis quam maximus vel. Integer a lacus mauris.
</div>
</div>
效果如下图:
网格布局和其它布局方法的联系
CSS 网格布局作为实现布局的一个完整系统,其设计使之和 CSS 其它部分能协同合作。
网格和弹性盒
CSS 网格布局和弹性盒布局的主要区别在于 CSS 弹性盒布局是为一维布局服务的(沿横向或纵向的),而网格布局是为二维布局服务的(同时沿着横向和纵向)。
案例1:
自动填充网格轨道
我们可以通过使用 repeat
方法,配合 auto-fill
和 auto-fit
属性,创建类似弹性盒的效果,同时保证内容严格按照行和列的固定规则排列。
.wrapper {
width: 700px;
height: 70px;
text-align: center;
display: grid;
grid-template-columns: repeat(auto-fill, 200px);
border: 2px solid aqua;
}
.wrapper>div {
background-color: var(--bg);
}
<div class="wrapper">
<div style="--bg:blue">One</div>
<div style="--bg:pink">Two</div>
<div style="--bg:yellow">Three</div>
</div>
案例2:
使用 flex 布局里面的 flex 属性,平均分配每一个项目,然后用 gap 来给它们调间距。
.wrapper {
display: flex;
flex-direction: row;
gap: 20px;
width: 700px;
height: 70px;
text-align: center;
border: 2px solid aqua;
}
.wrapper>div {
flex: 1;
background-color: var(--bg);
}
<div class="wrapper">
<div style="--bg:blue">One</div>
<div style="--bg:pink">Two</div>
<div style="--bg:yellow">Three</div>
<div class="box4" style="--bg:orange">Four</div>
<div class="box5" style="--bg:yellowgreen">Five</div>
</div>
—————— 如有错误,请联系 2822895719@qq.com,会立即更改,感谢参考!