likes
comments
collection
share

grid基础用法解析

作者站长头像
站长
· 阅读数 88

什么是grid布局

grid布局是二维基于网格的布局模式,它与我们上一篇中提到的flex布局,gpt上是这样回答的:

Flex布局主要针对一维布局(行或者列),可以方便地实现垂直居中、水平居中等效果,适合用于构建小规模的布局结构。而Grid布局则是基于二维网格来实现布局,可以对整个页面进行划分,并且支持各种复杂布局,比如交错布局、网格布局等等,适合用于构建大规模的布局结构。 具体区别如下:

  1. 方向不同:Flex布局只能沿着主轴(row 或 column)方向布局,不能同时控制两个方向,而Grid布局可以同时控制行列两个方向。
  2. 间隔不同:Flex布局无法设置单个子元素之间的间距,只能通过给父元素添加 padding 或 margin 来实现;而Grid布局可以通过 grid-column-gap 和 grid-row-gap 属性设置单元格之间的间距。
  3. 对齐方式不同:Flex布局提供了justify-content 和 align-items属性用于控制子元素在主轴和交叉轴上的对齐方式,而Grid布局提供了justify-items 和 align-items属性用于控制单元格内子元素的对齐方式。
  4. 排列方式不同:Flex布局使用flex-direction 属性控制子元素的排列方式,可以是 row(水平排列)或 column(垂直排列),而Grid布局使用grid-template-columns 和 grid-template-rows属性控制单元格的宽度和高度,从而控制子元素的排列方式。

grid-template-columns与grid-template-rows

<div class="container">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
</div>
<style>
    .container {
        width: 300px;
        border: 1px solid #ccc;
        padding: 8px;
        display: grid;
        grid-template-columns: 40px 80px 100px 100px 40px;
        grid-template-rows: 25% 100px auto;
    }
    .item {
        height: 50px;
        border: 1px solid #000;
    }
</style>

grid基础用法解析

从上图可以看出,在所有子元素给定宽度时候,没有自动换行,并且超出了预期的区域,如果需要在一行展示,可以将其中某个给定宽度,赋值auto,例如:grid-template-columns: 40px 80px auto 100px 40px;,则效果如下:

grid基础用法解析

可以看出,第三个子元素宽度自适应,比之前的横向占的空间小了。

.container {
    width: 300px;
    border: 1px solid #ccc;
    padding: 8px;
    box-sizing: border-box;
    display: grid;
    grid-template-columns: 40px 80px 100px 100px 40px;
    grid-template-rows: 10% 30% 200px;
}
.item {
    border: 1px solid #000;
}

grid基础用法解析

同样的,grid-template-rows里面的参数也同样可以使用auto代替。当多个重复数字时候,可以使用缩写的方式,例如:

.container { grid-template-columns: 70px 70px 70px 70px 100px;}
/* 等价于 */
.container { grid-template-columns: repeat(4, 70px) 100px; }  

grid基础用法解析

特殊单元fr

特殊单元fr支持在固定子元素宽度的情况下,将剩余的部分,分成指定的分数,例如:

<div class="container">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
</div>
<style>
    .container {
        width: 300px;
        border: 1px solid #ccc;
        padding: 8px;
        box-sizing: border-box;
        display: grid;
        grid-template-columns: 1fr 1fr 1fr;
    }
    .item {
        border: 1px solid #000;
        height: 50px;
    }
</style>

grid基础用法解析

像这样,平均分为了指定的大小,也换行了。如果我们将上述的1fr 1fr 1fr改成1fr 2fr 1fr,又会是什么样的效果呢?

grid基础用法解析

截止目前,每行都是三个元素展示,这是因为我们在单行定义了三个份额,如果要展示两个,我们只需要将上述代码中的1fr 2fr 1fr改成1fr 2fr,就会出现一行展示两个的效果了,效果如下:

grid基础用法解析

使用grid-template-areas实现简单布局

<div class="container">
    <div class="item-a item">header</div>
    <div class="item-b item">main</div>
    <div class="item-c item">sidebar</div>
    <div class="item-d item">footer</div>
</div>
<style>
    .item { border: 1px solid #000; }
    .item-a { grid-area: header; }
    .item-b { grid-area: main; }
    .item-c { grid-area: sidebar; }
    .item-d { grid-area: footer; }
    .container {
        width: 300px;
        height: 200px;
        border: 1px solid #ccc;
        padding: 8px;
        display: grid;
        grid-template-columns: 1fr 1fr 1fr 1fr;
        grid-template-rows: auto;
        grid-template-areas:
            "header  header  header  header"
            "sidebar .       main    main"
            "footer  footer  footer  footer";
    }
</style>
  • <grid-area-name>:在grid-area中指定的网格区域名字
  • .:一个句点表示一个空的网格单元
  • none:没有网格区域被定义

在上面的代码里,grid-area属性指定网格模板,grid-template-areas属性对模板进行排版排序,为了方便对比理解,我们将代码中排序的顺序与效果图放在一起进行对比,如下图:

grid基础用法解析

我们不难看出,因为我们将网格分为了四等份grid-template-columns: 1fr 1fr 1fr 1fr;,所以排序时候,一行也按照多个进行排列,相同模板的单元会被自动合并在一起。或许有同学会问,那如果我分为四等份,但是我排版时候,一行排五个,会怎样呢?使用none排版又怎样呢?我们也给出了效果图如下(左侧为一行排列五个效果;右侧为none效果):

grid基础用法解析 grid基础用法解析

grid-column-gap/grid-row-gap/grid-gap

在上面,我们已经能够通过grid进行简单的布局,但是我们可以发现,子元素网格模板之间是紧挨着的,没有间隙,并不符合我们想象中的样子,所以我们就需要添加行列模板之间的间隙。话不多说,我们直接上代码:

<div class="container">
    <div class="item-a item">header</div>
    <div class="item-b item">main</div>
    <div class="item-c item">sidebar</div>
    <div class="item-d item">footer</div>
</div>
<style>
    .item { border: 1px solid #000; }
    .item-a { grid-area: header; }
    .item-b { grid-area: main; }
    .item-c { grid-area: sidebar; }
    .item-d { grid-area: footer; }
    .container {
        width: 300px;
        height: 200px;
        border: 1px solid #ccc;
        padding: 8px;
        display: grid;
        grid-template-columns: 1fr 1fr 1fr 1fr;
        grid-template-rows: auto;
        grid-template-areas:
            "header  header  header  header"
            "sidebar .       main    main"
            "footer  footer  footer  footer";
        grid-column-gap: 16px; 
        grid-row-gap: 32px; 
    }
</style>

grid基础用法解析 grid基础用法解析

从图中我们可以看出,在网格模板中,行之间的间隙是32px,列之间的间隙是16px。

我们可以将两个属性写在一起,例如:grid-gap: <grid-column-gap> <grid-row-gap>;

justify-items网格对齐方式

网格默认stretch对齐,填充整个网格区域的宽度,start,center,end对齐会失去平铺的效果,效果如下:

grid基础用法解析 grid基础用法解析 grid基础用法解析 grid基础用法解析

align-items网格对齐方式

网格默认stretch对齐,填充整个网格区域的宽度,start,center,end对齐会失去平铺的效果,效果如下:

grid基础用法解析 grid基础用法解析 grid基础用法解析 grid基础用法解析

justify-content/align-content

当给定的宽度和小于父元素宽度或高度就会出现盒子边缘大量空白,但是想要两端对齐或者环绕对齐,就可以这样做,情景复现:

<div class="container">
    <div class="item-a item">header</div>
    <div class="item-b item">main</div>
    <div class="item-c item">sidebar</div>
    <div class="item-d item">footer</div>
</div>
<style>
    .item { border: 1px solid #000; }
    .item-a { grid-area: header; }
    .item-b { grid-area: main; }
    .item-c { grid-area: sidebar; }
    .item-d { grid-area: footer; }
    .container {
        width: 300px;
        height: 200px;
        border: 1px solid #ccc;
        padding: 8px;
        display: grid;
        grid-template-columns: 50px 50px 50px 50px;
        grid-template-rows: 50px 50px 50px;
        grid-template-areas:
            "header  header  header  header"
            "sidebar main    main    main"
            "footer  footer  footer  footer";
    }
</style>

grid基础用法解析

下面是一张在W3CSchool找到的关于justify-content的描述及效果图:

  • start:左对齐
  • end:右对齐
  • center:居中对齐
  • stretch:填充网格容器
  • space-around:在每个网格子项中间放置均等的空间,在始末两端只有一半大小
  • space-between:两边对齐,在每个网格子项中间放置均等的空间,在始末两端没有空间
  • space-evenly:网格间隔相等,包括始末两端

grid基础用法解析

下面是一张在W3CSchool找到的关于align-content的描述及效果图:

  • start:顶部对齐
  • end:底部对齐
  • center:居中对齐
  • stretch:填充网格容器
  • space-around:在每个网格子项中间放置均等的空间,在始末两端只有一半大小
  • space-between:上下对齐,在每个网格子项中间放置均等的空间,在始末两端没有空间
  • space-evenly:在每个网格子项中间放置均等的空间,包括始末两端

grid基础用法解析

我们通过justify-contentalign-content,对上面我们的布局进行调整,代码及效果如下:

<div class="container">
    <div class="item-a item">header</div>
    <div class="item-b item">main</div>
    <div class="item-c item">sidebar</div>
    <div class="item-d item">footer</div>
</div>
<style>
    .item { border: 1px solid #000; }
    .item-a { grid-area: header; }
    .item-b { grid-area: main; }
    .item-c { grid-area: sidebar; }
    .item-d { grid-area: footer; }
    .container {
        width: 300px;
        height: 200px;
        border: 1px solid #ccc;
        padding: 8px;
        display: grid;
        grid-template-columns: 50px 50px 50px 50px;
        grid-template-rows: 50px 50px 50px;
        grid-template-areas:
            "header  header  header  header"
            "sidebar main    main    main"
            "footer  footer  footer  footer";
        justify-content: space-around;
        align-content: space-around;
    }
    </style>

grid基础用法解析

通过grid-auto-flow控制排列方式

  • row:按照行依次从左到右排列
  • column:按照列依次从上到下排列
  • dense:按先后顺序排列

grid-auto-flow: row

<div class="container">
    <div class="item-a item">item-a</div>
    <div class="item-b item">item-b</div>
    <div class="item-c item">item-c</div>
    <div class="item-d item">item-d</div>
    <div class="item-e item">item-e</div>
</div>
<style>
    .item {
        border: 1px solid #000;
    }
    .container {
        width: 300px;
        height: 200px;
        border: 1px solid #ccc;
        padding: 8px;
        display: grid;
        grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
        grid-template-rows: repeat(5, 40px);
        grid-auto-flow: row;
    }
    .item-a {
        grid-column: 1;
        grid-row: 1 / 2;
        background-color: #ccc;
    }
    .item-c {
        grid-column: 3;
        grid-row: 2 / 4;
        background-color: #ccc;
    }
    .item-e {
        grid-column: 5;
        grid-row: 1 / 3;
        background-color: #ccc;
    }
</style>

grid基础用法解析

从上图中我们可以看出,grid-row属性,最小值为1,截止于给定值的上一个值,例如item-e,给定的值为第一行到第三行,但实际上只渲染了前两行。

<div class="container">
    <div class="item-a item">item-a</div>
    <div class="item-b item">item-b</div>
    <div class="item-c item">item-c</div>
    <div class="item-d item">item-d</div>
    <div class="item-e item">item-e</div>
</div>
<style>
    .item {
        border: 1px solid #000;
    }
    .container {
        width: 300px;
        height: 200px;
        border: 1px solid #ccc;
        padding: 8px;
        display: grid;
        grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
        grid-template-rows: repeat(6, 40px);
        grid-auto-flow: column;
    }
    .item-a {
        grid-row: 1;
        grid-column: 1 / 2;
        background-color: #ccc;
    }
    .item-c {
        grid-row: 3;
        grid-column: 2 / 4;
        background-color: #ccc;
    }
    .item-e {
        grid-row: 5;
        grid-column: 1 / 3;
        background-color: #ccc;
    }
</style>

grid基础用法解析

justify-self/align-self

justify-self属性介绍
  • start – 让内容在网格区域左对齐
  • end – 让内容在网格区域右对齐
  • center – 让内容在网格区域中间对齐
  • stretch – 填充着呢个网络区域的宽度(默认值)
justify-self: start | end | center | stretch
align-self属性介绍
  • start – 让内容在网格区域上对齐
  • end – 让内容在网格区域下对齐
  • center – 让内容在网格区域中间对齐
  • stretch – 填充着呢个网络区域的高度(默认值)
align-self: start | end | center | stretch

将上面案例的文字,横向居中,纵向也居中:

<div class="container">
    <div class="item">hello</div>
    <div class="item">hello</div>
    <div class="item">hello</div>
    <div class="item">hello</div>
    <div class="item">hello</div>
</div>
<style>
    .container {
        width: 300px;
        border: 1px solid #ccc;
        padding: 8px;
        box-sizing: border-box;
        display: grid;
        grid-template-columns: 1fr 1fr 1fr;
    }
    .item {
        border: 1px solid #000;
        height: 50px;
        display: grid;
        align-items: center;
        justify-items: center;
    }
</style>

grid基础用法解析

小结

grid布局是一种灵活而强大的CSS布局方法,我们可以以网格形式排列页面元素。与传统的基于盒模型的布局技术相比,grid布局提供了更直观、更简单的方式来定义和控制页面布局。

flex布局的优点:

  1. 简单易学:相对于grid,flex更容易上手。
  2. 适用于一维布局:flex最擅长处理一维布局(即沿着一个轴线排列元素),比如垂直居中、水平布局等。
  3. 响应式布局:flex可用于创建弹性、响应式布局,可以在不同设备上灵活适配。
  4. 浏览器支持较好:flex已成为布局的标准之一,并且大多数浏览器都支持。

flex布局的缺点:

  1. 二维布局限制:相对于grid,flex更适用于处理一维布局,因此在需要处理复杂布局时,它的能力会受到限制。
  2. 对齐方式受限:使用flex时,对齐方式只能沿着主轴线和交叉轴线两个方向进行,这也就意味着某些特殊的布局需求可能无法满足。

grid布局的优点:

  1. 适用于二维布局:grid最大的优势在于其能够轻松处理复杂的二维布局,包括列和行。
  2. 灵活性强:grid具有较高的灵活性,可以轻松地实现响应式布局,同时还可以应对各种尺寸和设备。
  3. 对齐方式灵活:相比flex,grid对齐方式的限制更少,用户可以将元素沿着任意方向进行排列。

grid布局的缺点:

  1. 学习曲线较陡峭:相对于flex,gid的学习曲线可能会更陡峭一些。
  2. 浏览器兼容性问题:虽然大多数浏览器都支持grid,但在一些老旧浏览器上可能存在兼容性问题。

虽然grid布局相比flex布局更加强大,但是我们在使用的过程中,还是要二者配合使用,才能更快更高效的实现我们需要的布局。

转载自:https://juejin.cn/post/7238978371689381945
评论
请登录