CSS-Grid页面网格布局从未如此简单

38次阅读

共计 5175 个字符,预计需要花费 13 分钟才能阅读完成。

页面布局从来就不是一件让人省心的事!

如果 pc 端的 两列布局 、表格布局、 圣杯布局 等已经让你心力交瘁!那么移动端更加五花八门的布局肯定也是让你吃尽苦头!table 不知道你用过没?bootstrap 用过没?antd 用过没?

这些看似花里胡哨的布局,其实就像是一张网,如果刚开始布局的时候就大局在握,后面就有源可寻!如果开始没梳理好,后面东改西补,你可能会想删代码跑路 (不能跑)… 前面文章有了解过 flex 布局(基于轴线的布局方式)像是 一维布局 。这里的 Grid 布局(基于网格式布局),在页面排版上将 容器 分成更为明显的块级 网格,从线(flex 轴线)到面(grid 网格)会使 css 布局更加便利!

一、Grid 概念

bootstrap 的栅栏格你如果了解过,可能会更好的理解这里的 grid!没有用过也没关系,下面是 grid 一些概念,对造上面的图,方便理解使用 grid。

  • 容器:采用网格布局的节点区域就叫做容器。
<div className="cover">
   <div className="item item1 red">1</div> //item 是项目
   <div className="item item2 black">2</div>
</div>//cover 就是容器

.cover{display: grid;}
  • 网格线:用来分割容器的线。分为水平网格线和垂直网格线,可以将容器分割成行和列。
  • 行和列:水平分割线将容器分割成行(n 行需要 n + 1 条水平分割线);垂直网格线将容器分割成列(n 列需要 n + 1 条垂直分割线)
  • 单元格:行和列交叉形成了单元格
  • 项目:容器内部采用网格定位的子元素,只能是顶层元素,称为 ” 项目 ”

要明白单元格与项目不是一回事。不要混淆了。

概念大致明白了?那就通过 容器 项目 的属性来进行网格式布局吧。

二、容器属性

下面主要通过 7 个属性来设置设置构建容器。

  • grid-template-columns/grid-template-rows 设置列 / 行 内容 的属性
  • grid-gap 设置列 / 行 间距 的属性
  • grid-template-areas 设置单元格 区域 的属性
  • grid-auto-flow 设置单元格 方向 属性
  • place-items 设置单元格内 内容排列位置 的属性
  • place-content 设置 整个内容区域在容器里面的位置 的属性
  • grid-auto-columns/grid-auto-rows 设置超出原有网格的 单元格 属性

1.grid-template-columns/grid-template-rows

通过 display:grid 指定节点使用网格布局后,要开始构建我们的行和列了。

grid-template-columns 设置列属性;
grid-template-rows 设置行属性;

这个属性可以用来设置 行高和列宽,设置的参数的值的方式有很多种写法:

下面设置一个 3 行 4 列 的表格,每个单元格的空间都是 100px;下面主要以 列来做示例 ,行的用法是一样的哦。这个属性值比较多, 要耐心看

1》使用绝对单位

grid-template-columns: 100px 100px 100px 100px;
grid-template-rows: 100px 100px 100px;

2》使用百分比 %

除了使用单位 px,还可以使用 %;

grid-template-columns: 25% 25% 25% 25%;
grid-template-rows: 33% 33% 33%;

3》使用 repeat 方法

当有网格很多且重复时,可以使用 repeat。repeat 接受两个参数,第一个参数是重复的次数,第二个参数是所要重复的值。

grid-template-rows: repeat(3 , 33%);
grid-template-columns: repeat(4, 25%);

repeat 除了重复值,还可以 重复模式

grid-template-columns: repeat(2, 100px 100px);

假如 repeat 里第一个参数改为 3,表示重复 3 次上述模式,所以下图里的单元格空间已经超出容器了,假如我们不想让它超出,想让容器 自动判断是否填充 ,可以使用auto-fill 关键字。

grid-template-columns: repeat(auto-fill, 100px 20px 80px);

4》fr 关键字
fr(fraction 的缩写,意为 ” 片段 ”),如果两列的宽度分别为 1fr 和 2fr,就表示后者是前者的两倍。也可以结合 px 使用,会对剩余空间按照 fr 进行分配。

grid-template-columns: 50px 3fr 1fr 2fr;

5》minmax()方法

minmax()接受 2 个参数,最小值和最大值 长度范围 ,该列 / 行的大小会根据剩余空间进行自动分配,大小在 长度范围 内。

grid-template-columns:150px 1fr 1fr minmax(50px, 150px);

6》auto 关键字

auto 关键字表示由浏览器自己决定长度。

grid-template-columns:100px auto 130px 100px;

第二列会根据剩余空间自动分配空间。

7》网格线的名称

除了设置大小,也能设置网格线的名称,使用方括号,指定每一根网格线的名字,方便以后的引用。4 列就需要是 5 条分割线,分割线的名称可以重复。

grid-template-columns: [c1] 100px [c2] 100px [c1] 100px [c3] auto [c4];

2.grid-gap

grid-gap 属性用来设置行 / 列间距的,是 grid-row-gap 属性、grid-column-gap 属性,的合并简写。这 3 个属性 最新标准也可不写前缀,写为row-gap、column-gap、gap

grid-row-gap:10px;
grid-column-gap:20px;
等价于下面代码:grid-gap:10px 20px;
等价于:gap:10px 20px;

3.grid-template-areas

网格布局允许指定 ” 区域 ”(area),一个区域由单个或多个单元格组成。grid-template-areas 属性用于定义区域。

grid-template-areas: 
    'a a a a'
    'b b b b' 
    'd e . g';
    
1. 将单元格写成相同的名字就可以合并区域
2. 如果某些区域不需要利用,则使用 "点"(.)表示。

区域的命名会影响到 网格线。每个区域的起始网格线,会自动命名为区域名 -start,终止网格线自动命名为区域名 -end。

4.grid-auto-flow

划分网格以后,容器的子元素 (项目) 会按照顺序,自动放置在每一个网格。默认的放置顺序是 ”先行后列 “,即先填满第一行,再开始放入第二行。
grid-auto-flow 决定放置顺序,默认值是 row。

grid-auto-flow: column;// 可将放置顺序改为先列后行

当对 ** 项目 ** 进行指定位置时,看下图,项目 1 上面会有一片无人使用的区域。.item1 {
    grid-row-start: 2;
    grid-row-end: 4;  
}

grid-auto-flow: column dense;
//dense 表示要尽可能紧密填满,尽量不出现空格。

5.place-items

从前面的一些图可以看出来,网格布局界限十分清晰,但是我们的 项目 内容却始终躲靠在单元格的左上角,显得十分的胆怯。哼!我们自然要把它揪出来。

place-items 决定项目的水平和垂直位置,是justify-items(水平位置) 属性、align-items(垂直位置) 属性的合并缩写:

place-items:center center;等价于:justify-items: center 
align-items: center

当然属性值除了 center,具体属性值如下:

start:对齐单元格的起始边缘。end:对齐单元格的结束边缘。center:单元格内部居中。stretch:拉伸,项目大小没有指定时 - 占满单元格的整个宽度(默认值)。

如果省略第二个值,则浏览器认为与第一个值相等。

6.place-content

我们把 容器 设置大点,就会发现 整个内容区域在容器里面的位置 也是躲靠在左上角的,可以通过 place-content 来设置。使用方法大致同等上面place-items

place-content 是 justify-content(水平方向)属性、align-content(垂直方向)属性的缩写。

place-content:center 

属性有以下取值:


start - 对齐容器的起始边框。end - 对齐容器的结束边框。center - 容器内部居中。stretch - 项目大小没有指定时,拉伸占据整个网格容器。space-around - 每个项目两侧的间隔相等。所以,项目之间的间隔比项目与容器边框的间隔大一倍

space-between - 项目与项目的间隔相等,项目与容器边框之间没有间隔。space-evenly - 项目与项目的间隔相等,项目与容器边框之间也是同样长度的间隔。

7. grid-auto-columns/grid-auto-rows

当项目超出容器,设置超出原有网格的 单元格 属性时,超出的单元格大小将于项目大小一样。可以通过 grid-auto-columns/grid-auto-rows 设置超出部分单元格的大小。

设置一个行超出容器的项目,超出部分行高将于项目一样高。.item1 {
    grid-row-start: 4;
    grid-row-end: 5;  
}
设置超出部分行高为 200px,如下图
grid-auto-rows: 200px; 

还有两种简写方法如下:

grid-template 属性是 grid-template-columns、grid-template-rows 和 grid-template-areas 这三个属性的合并简写形式。

grid 属性是 grid-template-rows、grid-template-columns、grid-template-areas、grid-auto-rows、grid-auto-columns、grid-auto-flow 这六个属性的合并简写形式。

三、项目属性

  • grid-column/grid-row 设置 项目位置
  • grid-area 设置项目 放置区域
  • place-self 设置项目 在单元格内的位置

1.grid-column/grid-row

上面已经用到过这个属性,就是设置项目在容器中的位置。
grid-column 是grid-column-start(左边框所在的垂直网格线)、grid-column-end(右边框所在的垂直网格线)的缩写。
grid-row 是grid-row-start(上边框所在的水平网格线)、grid-row-end(下边框所在的水平网格线)的缩写。

.item-1 {
  grid-column: 1 / 3;
  grid-row: 1 / 2;
}
/* 等同于 */
.item-1 {
  grid-column-start: 1;
  grid-column-end: 3;
  grid-row-start: 1;
  grid-row-end: 2;
}
1. 可以通过数字指定第几根线。下面只设置了列的开始和结束,行没设置,则会在默认位置。.item1 {
    grid-column-start: 1;
    grid-column-end: 2;  
 }
2. 也可以设置为指定为通过 **grid-template-columns** 设置的网格线的名字。grid-template-columns: [c1] 100px [c2] 100px [c1] 100px [c3] 100px [c4];
.item1 {
    grid-column-start: c2;
    grid-column-end: c3;  
  }

3. 使用 span 关键字,表示 "跨越",即左右边框(上下边框)之间跨越多少个网格。.item1 {
    grid-column-start: 2;  
    grid-column-end: span 2; 
 }
等价于:.item1 {grid-column:2 / span 2}

2.grid-area

设置项目在 容器 中的区域位置。与上面通过分割线的只用一样,所以也能做为分割线 4 个属性的缩写。

grid-template-areas:
    'a a a a'
    'a a a a'
    'd c c c'
.item1 {grid-area: a} 

等价与:.item1 {grid-area: 1 / 1 / 1 / span 4}

3.place-self

与 place-items 用法一致,但只作用于单个项目, 能覆盖 place-items 的值。是 justify-self(设置单元格内容的水平位置 左中右)、align-self(设置单元格内容的垂直位置上中下)的缩写。

.cover{place-items:center}
.item1 {place-self: start}

参考文章

如有不妥!欢迎指正

正文完
 0