CSS Grid 网格布局全解析
介绍
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: ro ws / co lu mns;
我们上面的例子使用这个简写语法后,看起来非常整齐。
.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个框中:
- grid-column-start
- grid-column-end
- grid-row-start
- grid-row-end
前两个属性对应于垂直网格线,也就是列网格线的开始和结束。 最后两个属性是指水平网格线,也就是行网格线的开始和结束。 让我们分配正确的网格线编号来移动第 6 个框。
.box:nth-child(6)
{
grid-row-start:;
grid-row-end:;
grid-column-start:;
grid-column-end:;
}
还有两个简写属性用于将行和列的开始网格线和结束网格线设置在一起。
.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 Grid 网格布局全解析的更多相关文章
- CSS Grid网格布局全攻略
CSS Grid网格布局全攻略 所有奇技淫巧都只在方寸之间. 几乎从我们踏入前端开发这个领域开始,就不停地接触不同的布局技术.从常见的浮动到表格布局,再到如今大行其道的flex布局,css布局技术一直 ...
- 轻松上手CSS Grid网格布局
今天刚好要做一个好多div格子错落组成的布局,不是田字格,不是九宫格,12个格子这样子,看起来有点复杂.关键的是笔者有点懒,要写那么多div和css真是不想下手啊.多看了两眼,这布局不跟网格挺像吗?c ...
- CSS Grid 网格布局教程
一.概述 网格布局(Grid)是最强大的 CSS 布局方案. 它将网页划分成一个个网格,可以任意组合不同的网格,做出各种各样的布局.以前,只能通过复杂的 CSS 框架达到的效果,现在浏览器内置了. 上 ...
- css - Grid网格布局
.wrapper{ display: grid; grid-template-columns: 100px 100px 100px; grid-template-rows: 100px 100px 1 ...
- css grid 网格布局
前几天研究了一下这个布局方式,笔记待更新 先放一下学习站点 文档 我应该尝试使用CSS Grid Layout的IE实现吗 https://hacks.mozilla.org/2018/02/css- ...
- 【CSS】343- CSS Grid 网格布局入门
CSS Grid(网格) 布局使我们能够比以往任何时候都可以更灵活构建和控制自定义网格.Grid(网格) 布局使我们能够将网页分成具有简单属性的行和列. 它还能使我们在不改变任何HTML的情况下,使用 ...
- grid网格布局使用
定义 grid布局是指对网页进行划分成一个一个网格,然后根据自己的要求,可以任意组合. 以前写类似的功能,很麻烦,需要写很多的CSS去控制,有了grid就很方便了,可以随意进行组合. 跟flex有很多 ...
- 不用bootstrap,只用CSS创建网格布局
本文译自[http://j4n.co/blog/Creating-your-own-css-grid-system],英语好的,可直接查看原网页,不需要FQ. 翻译拿不准的地方会有英文原文,方便大家理 ...
- python之tkinter使用-Grid(网格)布局管理器
# 使用tkinter编写登录窗口 # Grid(网格)布局管理器会将控件放置到一个二维的表格里,主控件被分割为一系列的行和列 # stricky设置对齐方式,参数N/S/W/E分别表示上.下.左.右 ...
随机推荐
- Linux下用户和组管理
用户与组之间的关系是,组下面有若干个用户,每个用户必须从属于唯一一个组.组可以理解为权限的集合.用户管理的命令有:useradd, userdel, usermod, passwd, chsh, ch ...
- 决策树学习笔记(Decision Tree)
什么是决策树? 决策树是一种基本的分类与回归方法.其主要有点事模型具有可得性,分类速度快.学习时,利用训练数据,根据损失函数最小化原则建立决策树模型:预测时,对新数据,利用决策树模型进行分类. 决策树 ...
- qwe框架- CNN 实现
CNN实现 概述 我在qwe中有两种,第一种是按照Ng课程中的写法,多层循环嵌套得到每次的"小方格",然后WX+b,这样的做法是最简单,直观.但是效率极其慢.基本跑个10张以内图片 ...
- JFFS2 文件系统及新特性介绍
简介: JFFS2 是一个开放源码的项目(www.infradead.org). 它是在闪存上使用非常广泛的读/写文件系统,在嵌入式系统中被普遍的应用.这篇文章首先分析了在闪存上使用 JFFS2 的必 ...
- mysql常用基础操作语法(五)--对数据的简单条件查询【命令行模式】
1.单条件查询:select 字段名 from tablename where 条件: 2.简单多条件查询,使用&&或者between and等: 3.is null和is not n ...
- FusionCharts 2D柱状图和折线图的组合图
1.设计思路 (1)了解组合图的特性以及用法,选用图的类型: (2)设计出两根柱子和两根折线,分开展示. 2.设计步骤 (1)设计页面 Column2DLine.html: <!DOCTYPE ...
- dojo表格分页插件报错
dojo表格分页插件报错 (1)dojo/parser::parse() error ReferenceError {stack:(...),message:"layout is not d ...
- Srtuts2实现登录界面(不连接数据库)报错(一)
二月 28, 2014 11:32:02 下午 org.apache.catalina.core.AprLifecycleListener init 严重: An incompatible versi ...
- 为什么选择Netty作为基础通信框架?
在开始之前,我先讲一个亲身经历的故事:曾经有两个项目组同时用到了NIO编程技术,一个项目组选择自己开发NIO服务端,直接使用JDK原生的API,结果两个多月过去了,他们的NIO服务端始终无法稳定,问题 ...
- javascript中的内存管理和垃圾回收
前面的话 不管什么程序语言,内存生命周期基本是一致的:首先,分配需要的内存:然后,使用分配到的内存:最后,释放其内存.而对于第三个步骤,何时释放内存及释放哪些变量的内存,则需要使用垃圾回收机制.本文将 ...