侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

CSS Grid 网格布局全解析

前端  /  管理员 发布于 7年前   393

介绍

CSS Grid(网格) 布局使我们能够比以往任何时候都可以更灵活构建和控制自定义网格。 Grid(网格) 布局使我们能够将网页分成具有简单属性的行和列。它还能使我们在不改变任何HTML的情况下,使用 CSS 来定位和调整网格内的每个元素。它允许 HTML 纯粹作为内容的容器。HTML 结构不再受限于样式表现,比如不要为了实现某种布局而多次嵌套,现在这些都可以让 CSS 来完成。

定义一个网格

Grid(网格) 模块为 display 属性提供了一个新的值: grid 。当你将任何元素的 display 属性设置为 grid 时,那么这个元素就是一个 网格容器(grid container),它的所有直接子元素就成了 网格项(grid items)。

让我们创建创建一个 3×3 的布局,做一个 Tic-Tac-Toe (井字游戏) 棋盘。

首先,我们将写一些 HTML:

    <div class="game-board">      <div class="box"></div>      <div class="box"></div>      <div class="box"></div>      <div class="box"></div>      <div class="box"></div>      <div class="box"></div>      <div class="box"></div>      <div class="box"></div>      <div class="box"></div>    </div>

如您所见, .game-board div 是网格容器,而 .box div 是网格项。现在我们将通过 Grid 布局来实现 3×3 布局。

    .game-board     {        display: grid;        grid-template-rows: 200px 200px 200px;        grid-template-columns: 200px 200px 200px;    }

在这里,我还使用了其他两个属性。

grid-template-rows 属性允许我们指定网格中的行数及行的高度。那么你应该猜到另一个属性是干什么的了。

grid-template-columns 属性允许我们指定网格中的列数及列的宽度。您可以指定任何单位的尺寸大小,包括像素,百分比和其他单位 fr ,我们将在下一步学习。

fr 单位(等分)

fr 是为网格布局定义的一个新单位。它可以帮助你摆脱计算百分比,并将可用空间等分。

例如,如果在网格容器中设置这个规则: grid-template-rows: 2fr 3fr , 那么你的网格容器将首先被分成 2 行。然后将数字部分加在一起,这里总和为 5, 即 5 等分。

就是说,我们将有 2 行:第一排占据垂直空间的 2/5 。 第二排占垂直空间的 3/5 。

回到我们的 Tic-Tac-Toe 例子,我们使用 fr 代替 px 。我们想要的是,应该有3行3列。所以,我们只需要用 3 个 1fr 替换 3 个 200px 即可:

    .game-board     {        display: grid;        grid-template-rows: 1fr 1fr 1fr;        grid-template-columns: 1fr 1fr 1fr;    }

这里特别需要注意的是: fr 单位是等分可用空间,或者说剩余空间。看个例子

    .game-board     {        grid-gap:2px;        display: grid;        width:300px;        height:200px;        grid-template-rows: 100px 1fr 1fr;        grid-template-columns: 1fr 50px 1fr;    }

布局效果如图:

你会看到 fr 单位是将 总的尺寸 减去 单元格明确尺寸后,在等分剩余空间。 grid-gap 是间隔。

repeat() 函数

在某些情况下,我们可能有很多的列和行。在 grid-template 属性中指定每一个值可能会很乏味。幸运的是,有一个 repeat 函数 ,就像任何一个循环重复多少次输出某个给定值。它有两个参数。第一个是迭代次数,第二个是要重复的值。我们用 repeat 函数重写上面的例子。

    .game-board    {        display: grid;        grid-template-rows: repeat(3, 1fr);        grid-template-columns: repeat(3, 1fr);    }

等价于:

    .game-board     {        display: grid;        grid-template-rows: 1fr 1fr 1fr;        grid-template-columns: 1fr 1fr 1fr;    }

grid-template 属性

grid-template 属性是 grid-template-rows 和 grid-template-columns 的简写语法。 这是它的语法:grid-template: rows/columns;

我们上面的例子使用这个简写语法后,看起来非常整齐。

    .game-board    {        display: grid;        grid-template: repeat(3, 1fr) / repeat(3, 1fr);    }

看,只需使用 2 行代码,就可以使用网格布局创建 3×3 网格。

例子:

HTML

<div class="game-board">  <div class="box">X</div>  <div class="box">O</div>  <div class="box">O</div>  <div class="box">O</div>  <div class="box">X</div>  <div class="box">O</div>  <div class="box">O</div>  <div class="box">X</div>  <div class="box">X</div></div>

CSS

.game-board{    width: 600px;    height: 600px;    margin: 0 auto;  background-color: #34495e;  color: #fff;  border: 6px solid #2c3e50;  border-radius: 10px;        display: grid;    grid-template: repeat(3, 1fr) / repeat(3, 1fr);}.box{  border: 6px solid #2c3e50;  border-radius: 2px;  font-family: Helvetica;  font-weight: bold;  font-size: 4em;  display: flex;  justify-content: center;  align-items: center;}

网格线编号,网格单元格,网格轨道

网格线是存在于列和行每一侧的线。一组垂直线将空间垂直划分成列,而另一组水平线将空间水平划分成行。这意味着在我们之前的例子中,有四条垂直线和四条水平线包含它们之间的行和列。

在将网格项从一个位置跨越到另一个位置时,网格线变得非常有用。

网格轨道是两条线之间的空间。 网格轨道可以是一行或一列。

网格单元格很像表格单元,是两条相邻垂直线和两条相邻水平线之间的空间。 这是网格中最小的单位。

定位网格项

我采取了前面的例子的网格,并用数字从1到9标记每个单元格,而不是X或O,下面是它的样子:

假设我想将第 6 个框移到第 2 个框的位置。没有CSS网格,不改变 HTML 的情况下,这几乎是一个不可能的任务,至少对我而言。但是如果我们使用网格模块,改变网格中网格项的位置是一件轻而易举的事情。要将第6个框移到第2个框的位置,我们必须确切知道第2个框在哪里。通过网格线编号的帮助,我们可以很容易地找到这个位置。第二个方框位于第2条列网格线之后,第3条列网格线之前,第1条行网格线之下,第2条行网格线之上。现在我们可以使用以下属性将这些网格线编号分配到第6个框中:

  1. grid-column-start
  2. grid-column-end
  3. grid-row-start
  4. grid-row-end

前两个属性对应于垂直网格线,也就是列网格线的开始和结束。 最后两个属性是指水平网格线,也就是行网格线的开始和结束。 让我们分配正确的网格线编号来移动第 6 个框。

    .box:nth-child(6)    {        grid-row-start: 1;        grid-row-end: 2;        grid-column-start: 2;        grid-column-end: 3;    }

还有两个简写属性用于将行和列的开始网格线和结束网格线设置在一起。

    .box:nth-child(6)    {        grid-row: 1 / 2;        grid-column: 2 / 3;    }

此外,还有一个 grid-area 属性是所有四个上述属性的简写属性。 它按以下顺序取值:grid-area: <row-start> / <column-start> / <row-end> / <column-end>;

现在我们的例子可以写成这样

    .box:nth-child(6)    {        grid-area: 1 / 2 / 2 / 3;    }

上面的代码行也可以进一步减少。正如您所看到的,这个框只占用一行和一个列,所以我们只需要指定行和列的起始线,而无需结束线的值

    .box:nth-child(6)    {        grid-area: 1 / 2;    }

如果我们想要第6个框跨越两个框的区域呢? 这很容易通过将 column-end 值加 1 的办法来完成。

    .box:nth-child(6)    {        grid-area: 1 / 2 / 2 / 4;    }

您也可以使用 span 关键字和占据的 轨道数量,来代替指定 grid-row-end 和 grid-column-end 的结束网格线编号。 在这种情况下,第6个框是跨越 2 列和 1 行。

    .box:nth-child(6)    {        grid-area: 1 / 2 / 2 / span 2;    }

网格区域命名

grid-area 属性也可以用来命名网格的某一个部分,然后我们可以用 grid-template-areas 属性来定位。让我们创建一个简单的 bread-and-butter 布局,顶部有一个 top, nav,中间有 main 和 aside,下面是 footer。这是所需的HTML:

    <div class="container">      <header></header>      <nav></nav>      <main></main>      <aside></aside>      <footer></footer>    </div>

我们需要使用 grid-area 属性来命名每个区域:

    header    {      grid-area: header;      background-color: #9b59b6;    }         nav    {      grid-area: nav;      background-color: #3498db;    }         main    {      grid-area: main;      background-color: #2ecc71;    }         aside    {      grid-area: aside;      background-color: #f1c40f;    }         footer    {      grid-area: footer;      background-color: #1abc9c;    }

现在我们将使用 grid-template-areas 属性来指定每个网格区域所占据的行和列。 以下是我们如何做到的:

    .container    {          display: grid;          grid-template-rows: 1fr 5fr 1fr;          grid-template-columns: 2fr 5fr 3fr;          grid-template-areas:"header  header  header""nav     main    aside""footer  footer  footer";          grid-gap: .75em;    }

请注意,header 和 footer 单词重复三次。 这表明,header 和 footer 横跨 3 列的宽度。 你可以把它全部写在一行中,但是把每一行写在一个单独的行上很好,很干净。 你可以看到我在这里使用了一个新的属性 grid-gap 。 它所做的只是在两个网格区域之间添加一个间距。 你也可以使用 grid-row-gap 和 grid-column-gap 来为行和列指定不同的间距值。

例子:

HTML

<div class="container">  <header></header>  <nav></nav>  <main></main>  <aside></aside>  <footer></footer></div>

CSS

.container{  display: grid;  grid-template-rows: 1fr 5fr 1fr;  grid-template-columns: 2fr 5fr 3fr;  grid-template-areas:    "header header header"    "nav    main   aside"    "footer footer footer";  grid-gap: .75em;  background-color: #eee;  width: 100vw;  height: 100vh;}header{  grid-area: header;  background-color: #9b59b6;}nav{  grid-area: nav;  background-color: #3498db;}main{  grid-area: main;  background-color: #2ecc71;}aside{  grid-area: aside;  background-color: #f1c40f;}footer{  grid-area: footer;  background-color: #1abc9c;}

结论

CSS网格布局允许我们更快地布局,并且更容易控制。在本教程中,我们学习了如何用CSS网格来定义布局, fr 单位,repeat 函数和一些网格系统中特定的术语。我们还学习了如何使用网格线和网格命名区域在网格容器内定位网格项目

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


  • 上一条:
    css flex 弹性布局详解
    下一条:
    纯css实现多级折叠菜单折叠树效果
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 使用 Alpine.js 排序插件对元素进行排序(0个评论)
    • 在js中使用jszip + file-saver实现批量下载OSS文件功能示例(0个评论)
    • 在vue中实现父页面按钮显示子组件中的el-dialog效果(0个评论)
    • 使用mock-server实现模拟接口对接流程步骤(0个评论)
    • vue项目打包程序实现把项目打包成一个exe可执行程序(0个评论)
    • 近期文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2017-06
    • 2017-07
    • 2017-08
    • 2017-09
    • 2017-10
    • 2017-11
    • 2018-03
    • 2018-04
    • 2018-05
    • 2018-06
    • 2018-09
    • 2018-11
    • 2018-12
    • 2019-02
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2021-04
    • 2021-05
    • 2021-07
    • 2021-08
    • 2021-09
    • 2021-10
    • 2021-11
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-09
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-02
    • 2024-03
    • 2024-04
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客