解析CSS中的Grid布局完全指南

解析CSS中的Grid布局完全指南,第1张

解析CSS中的Grid布局完全指南

Grid 是一个基于二维网格布局的系统,有了它我们可以非常方便的实现过去很复杂布局,无需再使用 float , inline-block , position 这些本质上是 hack 的方法。


CSS网格布局擅长于将一个页面划分为几个主要区域,以及定义这些区域的大小、位置、层次等关系(前提是HTML生成了这些区域)。


它像表格一样,网格布局让我们能够按行或列来对齐元素。


然而在布局上,网格比表格更可能做到或更简单。


网格布局概念

在学习之前需要了解以下网格的几个概念。


网格轨道(Grid Tracks)

网格轨道 是两条网格线之间的空间。


它们通过使用属性 grid-template-columnsgrid-template-rows 在网格中定义。


上图中有两行三列,一行或一列就叫做轨道。


网格线(Grid Lines)

使用 Grid 布局在显式网格中定义轨道的同时会创建网格线。


网格线可以用它们的编号来寻址。


在从左到右的语言中, 列线1 将位于网格的左侧, 行线1 将位于其顶部。


线编号遵循文档的写入模式,因此在从右到左的语言中, 列线1 行将位于网格的右侧。


下面的图片展示了该网格的线编号,假设语言是从左到右的。


 

网络单元格(Grid Cell)

Grid 布局中,网络单元格是 CSS 网格中的最小单元。


它是四条网格线之间的空间,非常像表格单元格。


 

网格区域(Grid Areas)

网格区域是网格中由一个或者多个网格单元格组成的一个矩形区域。


本质上,网格区域一定是矩形的。


例如,不可能创建T形或L形的网格区域。


 

网格间距(Gutters)

网格间距是网格轨道之间的间距,可以通过 grid-column-gapgrid-row-gap 在Grid布局中创建。


 

使用 Grid 布局

和 flex 类似,要使用网格布局,首先要有一个容器,将一个元素的 display 设置为 grid 就可以得到一个 grid 容器。


容器的子项就是网格项(grid items),它有点类似 table 中的 td ,但是更加灵活。


float , clear , 和 vertical-align 元素对网格容器不起作用。


容器上的属性

网格模板

创建了网格容器,我们就可以定义这个网格有多少行有多少列,并且每一行每一列的大小。


grid-template-rows

我们使用 grid-template-rows 来显性定义网格有多少行。


它可以取如下的值:

none 关键字,表示不明确的网格。


所有的行和其大小都将由 grid-auto-rows 属性隐式的指定。


非负值的长度大小 :如 px, em, vw

百分比 :相对于网格容器的,如果是 inline-grid ,则百分比值将被视为 auto

flex :非负值,用单位 fr 来定义网格轨道大小的d性系数。


每个定义了 flex 的网格轨道会按比例分配剩余的可用空间

max-content 关键字,表示以网格项的最大的内容来占据网格轨道的

min-content 关键字,表示以网格项的最大的最小内容来占据网格轨道

auto 如果该网格轨道为最大时,等同于 max-content ,为最小时,等同于 min-content

grid-template-columns

它和 grid-template-rows 类似,一个设置网格行,一个是设置网格列。


.container {
    display: grid;
    grid-template-columns: 40px 50px auto 50px 40px;
    grid-template-rows: 25% 100px auto;
}

.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 100px 100px;
}

 

Grid 中可以使用的函数

在 Grid 布局中我们还可以使用如下 3 个函数

repeat()

repeat 函数可以以一种更简洁的方式去表示大量而且重复行的表达式。


比如上面 grid-template-columns: 1fr 1fr 1fr; 我们可以写成 repeat(3, 1fr)


它的第一个参数是重复的次数,而可以为 auto-fillauto-fit


auto-fill

如果容器有明确的大小或最大大小,则重复次数是最大可能的正整数,不会导致网格溢出其网格容器。


如果任何重复次数都会溢出,则重复次数为1。


auto-fit

auto-fill 的行为相同,只是在放置网格项后,任何空的重复轨道都会折叠。


#container {
  display: grid;
  grid-template-columns: repeat(2, 50px 1fr) 100px;
  grid-gap: 5px;
  box-sizing: border-box;
  height: 200px;
  width: 100%;
  background-color: #8cffa0;
  padding: 10px;
}

#container > div {
  background-color: #8ca0ff;
  padding: 5px;
}

 

minmax()

定义了一个长宽范围的闭区间。


它接受两个参数,最小值 和 最大值。


它返回这个区间中的值。


minmax(max-content, 300px) ,最大不能大于 300px

minmax(200px, 1fr) 最小不能小于 200px

fit-content()

它相当于 min(maximum size, max(minimum size, argument))


参数可以是长度值和百分比。


它在内容的最小值和参数中去一个最大值,然后再在内容的最大值中取一个最小值。


也就是当内容少时,它取内容的长度,如果内容多,内容长度大于参数长度时,它取参数长度。


grid-template-areas

这个属性网格区块,需要和 grid-area 配合使用,它的值可以是 none字符串


为字符串时每一个给定的字符串会生成一行,一个字符串中用空格分隔的每一个单元(cell)会生成一列。


多个同名的,跨越相邻行或列的单元称为网格区块(grid area)。


非矩形的网格区块是无效的。


#page {
  display: grid;
  width: 100%;
  height: 250px;
  grid-template-areas: "head head"
                       "nav  main"
                       "nav  foot";
  grid-template-rows: 50px 1fr 30px;
  grid-template-columns: 150px 1fr;
}

#page > header {
  grid-area: head;
  background-color: #8ca0ff;
}

#page > nav {
  grid-area: nav;
  background-color: #ffa08c;
}

#page > main {
  grid-area: main;
  background-color: #ffff64;
}

#page > footer {
  grid-area: foot;
  background-color: #8cffa0;
}

grid-template-areas 字符串,关联 grid item 的 grid-area ,用它定义一片区域。


grid-template

grid-template-rowsgrid-template-columnsgrid-template-areas 的简写。


它的值可以分三种情况:

  • none
  • 只有定义行和列时可以使用 rows/columns 语法,如 grid-template: 100px 1fr / 50px 1fr;
  • 当三个都有时,也用一个 / 分隔,而且它的右边也还是 columns ,但是它的左边语法是 <line-names>? <string> <track-size>? <line-names>?


.page {
    grid-template: [header-top] "a a a"     [header-bottom]
                   [main-top]   "b b b" 1fr [main-bottom]
                   / auto 1fr auto;
}
/*
line-names 是可选的,自定义名称,需要使用中括号包裹,它其实相当于注释
string 网格项 grid-area 的关联值
track-size 这一行的大小
*/
#page {
  display: grid;
  width: 100%;
  height: 200px;
  grid-template: [header-left] "head head" 30px [header-right]
                 [main-left]   "nav  main" 1fr  [main-right]
                 [footer-left] "nav  foot" 30px [footer-right]
                 / 120px 1fr;
}

header {
  background-color: lime;
  grid-area: head;
}

nav {
  background-color: lightblue;
  grid-area: nav;
}

main {
  background-color: yellow;
  grid-area: main;
}

footer {
  background-color: red;
  grid-column: foot;
}

 

grid-row-gap / row-gap

用来设置行元素之间的间隙(gutter) 大小。


它的值可以是长度值、百分比和 normal


CSS Grid Layout 起初是用 grid-row-gap 属性来定义的,目前逐渐被 row-gap 替代。


但是,为了兼容那些不支持 row-gap 属性的浏览器,你需要使用带有前缀的属性。


.box{
    grid-row-gap: 1em;
}

 

grid-column-gap / column-gap

用来设置元素列之间的间隔 (gutter) 大小。


它的值可以是长度值、百分比和 normal


normal 在 多列布局 时默认间隔为1em,其他类型布局默认间隔为 0。


grid-row-gap 一样,它渐渐被 column-gap 取代。


.page {
    grid-column-gap: 1em;
}

 

grid-gap / gap

是上面两个属性的简写,语法是 row-gap column-gap


如果没有 column-gap 那么它将被设置成跟 row-gap 一样的的值。


它也渐渐被 gap 取代。


#grid {
  display: grid;
  height: 200px;
  grid-template: repeat(3, 1fr) / repeat(3, 1fr);
  gap: 20px 5px;
}

#grid > div {
  background-color: lime;
}

 

隐式创建的行和列

css gird 会根据周围项目的大小和跨度自动调整网格上每个项目的位置。


比如:

.box {
  display: grid;
  grid-template: 25px / 100px 160px;
  background: #000;
}
.box * {
  background: #ccc;
}
.box *:nth-child(even) {
  background: #777;
}

我们只定义了一行,两列。


但是我们却有 5 个子元素。


CSS网格决定将它们扩展到隐式创建的空间,新建的隐式行中的列自动从先前指定的 grid-template-rows 属性继承行高。


grid-column-start , grid-column-end , grid-row-startgrid-row-end 这 4 个属性是 grid item 上的,它可以定义一个 grid item 的位置,如果我们将它的位置设置的超出我们定义的网格,那时也会隐式创建行或列。


grid-auto-rows

指定了隐式创建行的大小。


它的值可以是:

  • 长度值px em vmax
  • 百分比 :相对于网格容器
  • flex :非负值,用单位 fr 来定义网格轨道大小的d性系数。


    每个定义了 flex 的网格轨道会按比例分配剩余的可用空间

  • max-content 关键字,表示以网格项的最大的内容来占据网格轨道的
  • min-content 关键字,表示以网格项的最大的最小内容来占据网格轨道
  • auto 如果该网格轨道为最大时,等同于 max-content ,为最小时,等同于 min-content

它的值和 grid-template-rows 是一样的。


.box {
  display: grid;
  grid-template: 25px / 100px 160px;
  gap: 10px 20px;
  grid-auto-rows: 50px;
  background: #000;
}
.box * {
  background: #ccc;
}
.box *:nth-child(even) {
  background: #777;
}

 

grid-auto-columns

指定了隐式创建的网格的列宽。


它的取值和 grid-auto-rows 一样。


#grid {
  height: 100px;
  display: grid;
  grid-template-areas: "a a";
  grid-gap: 10px;
  grid-auto-columns: 200px;
}

#grid > div {
  background-color: lime;
}

 

grid-auto-flow

控制着自动布局算法怎样运作,精确指定在网格中被自动布局的元素怎样排列。


如果我们在一个 div 中写几个 div ,再对父级设置 display: grid; ,从视觉的角度可以发现没什么变化。


但是如果我们再将父级 div 加上一句 grid-auto-flow: column; 我们就发现现在子元素在一行显示,和d性盒子效果差不多。


grid-auto-flow 的值如下:

  • row指定自动布局算法按照通过逐行填充来排列元素,在必要时增加新行。


    (默认值)

  • column指定自动布局算法通过逐列填充来排列元素,在必要时增加新列。


在这两个关键字后面还可以加上 dense 关键字。


语法是 [ row | column ] || dense


该关键字指定自动布局算法使用一种“稠密”堆积算法,如果后面出现了稍小的元素,则会试图去填充网格中前面留下的空白。


这样做会填上稍大元素留下的空白,但同时也可能导致原来出现的次序被打乱。


如果省略它,使用一种「稀疏」算法,在网格中布局元素时,布局算法只会「向前」移动,永远不会倒回去填补空白。


这保证了所有自动布局元素「按照次序」出现,即使可能会留下被后面元素填充的空白。


grid-auto-flow: row;

grid-auto-flow: row dense;

 grid

grid 是 CSS 简写属性,它几乎包括上面提到的所有属性(除了 gap )。


与其他简写属性同样,若有次级属性未被声明,其将使用初始值。


另外,尽管此简写声明无法设置网格的槽(gutter),槽会被该声明重置。


它的值可以分为 3 类

grid-template

就和 grid-template 简写一样,如 grid: [linename1] "a" 100px [linename2];

grid-template-rows / [ auto-flow && dense? ] grid-auto-columns?

grid-template-rows 设置行高( grid-template-columns 被设置为 none ), / 后面的 auto-flow 必须要写( grid-auto-flow 被设置为 column ),最后 grid-auto-columns 置明确该如何自动重复列轨道( grid-auto-rows 属性设为 auto )。


grid: repeat(3, [line1 line2 line3] 200px) / auto-flow 300px;

[ auto-flow && dense? ] grid-auto-rows? / grid-template-columns

这种写法和上种写法相反,这种是设置 grid-template-columnsrows 属性为 none )。


可选的设置 grid-auto-rows 属性( columnsauto

grid: auto-flow dense / 30%;

网格项上的属性

 grid-row-start, grid-row-end, grid-column-start, grid-column-end

分别指定 grid item 在网格中的行起始位,行结束位,列起始位,列结束位。


这就需要了解之前介绍的网格线概念,横线(row)从上到下递增,竖线(column)从做到右递增,都是从 1 开始算。


它们可以取如下值:

auto 表示自动放置,自动跨度或默认 span 为 1 数字 表示网格线 span 数字 表示跨越几个格子, 数字 小于等于 0 无效。


如果超过网格大小会隐式创建行或列。


它和 table 有点相似

如果设置的位置超出指定大小,会得到不稳定的效果,应该避免这种情况。


.box {
  display: grid;
  grid: 100px 100px / 100px 100px;
  background: #000;
}
.box * {
  background: #ccc;
}
.box *:nth-child(even) {
  background: #777;
}
.box1 {
  grid-column-start: span 5;
}

 

grid-row, grid-column

grid-rowgrid-column 分别是上面 4 个属性简写。


它们值的语法是 start / end


如果只有一个值那么它是 startend 值为默认 auto


当列数未知时,可以使用 -1 让它一直扩展到网格末尾。


使用负值

 

grid-area

上面我们已经展示了 grid-areagrid-template-areas 结合的用法。


grid-area 其实是 grid-row-startgrid-column-startgrid-row-endgrid-column-end 的简写。


它的默认值是 grid-area: auto;

如果设置了 4 个值的话那么它的顺序是

grid-area: row-start / column-start / row-end / column-end;

如果设置了 3 个值,那么最后一个为 auto

如果设置了 2 个值,那么后两个为 auto

如果设置了 1 个值,那么后三个为 auto

如果第一项是 自定义表示 ,那么被忽略的都为自定义表示

.box1 {
  grid-area: a / a;
}

/* 相当于 */

.box1 {
    grid-row-start: a;
    grid-column-start: a;
    grid-row-end: a;
    grid-column-end: a;
}

网格项的内容对齐

我们可以使用 align-selfjustify-self 调整 grid item 的内容对齐方式。


align-self 用来垂直方向对齐, justify-self 用来水平方向对齐。


align-self

flex 布局也可以使用这个属性。


它常用如下 3 个值:

  1. start: 内容顶端对齐
  2. center: 内容垂直居中
  3. end: 内容底部对齐

 

justify-self

它常用如下 3 个值:

  • start / left : 内容左对齐
  • cneter : 内容水平居中
  • end / right : 内容右对齐

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


欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/web/617127.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-15
下一篇 2022-04-15

发表评论

登录后才能评论

评论列表(0条)

保存