参考链接

grid布局简介

  • CSS Grid(网格)布局,是一个二维的基于网络的布局系统。Flexbox 的出现很大程度上改善了我们的布局方式,但它的目的是为了解决更简单的一维布局,而不是复杂的二维布局(实际上 Flexbox 和 Grid 能协同工作,而且配合得非常好)。Grid(网格) 布局是第一个专门为解决布局问题而创建的 CSS 模块
  • 采用grid布局的元素,被称为grid容器(grid container),简称“容器”。其所有直接子元素(直接子元素的子元素不包含在内)自动成为容器成员,称为grid项目(grid item),简称“项目”

相关术语

Grid Container
  • 设置了 display: gird 的元素。 这是所有 grid item 的直接父项。 在下面的例子中,.container 就是是 grid container
<div class="container">
  <div class="item item-1"></div>
  <div class="item item-2"></div>
  <div class="item item-3"></div>
</div>
Grid Item
  • Grid 容器的孩子(直接子元素)。下面的 .item 元素就是 grid item,但 .sub-item不是
<div class="container">
  <div class="item"></div> 
  <div class="item">
    <p class="sub-item"></p>
  </div>
  <div class="item"></div>
</div>
Grid Line
  • 这个分界线组成网格结构。 它们既可以是垂直的(“column grid lines”),也可以是水平的(“row grid lines”),并位于行或列的任一侧。 下面例子中的黄线就是一个列网格线
    示意图
Grid Track
  • 两个相邻网格线之间的空间。 可以把它们想象成网格的列或行。 下面是第二行和第三行网格线之间的网格轨道
    示意图
Grid Cell
  • 两个相邻的行和两个相邻的列网格线之间的空间。它是网格的一个“单元”。 下面是行网格线1和2之间以及列网格线2和3的网格单元
    示意图
Grid Area
  • 四个网格线包围的总空间。 网格区域可以由任意数量的网格单元组成。 下面是行网格线1和3以及列网格线1和3之间的网格区域
    在这里插入图片描述

Grid 属性列表

Grid Container 的全部属性
  • display
  • grid-template-columns
  • grid-template-rows
  • grid-template-areas
  • grid-template
  • grid-column-gap
  • grid-row-gap
  • grid-gap
  • justify-items
  • align-items
  • justify-content
  • align-content
  • grid-auto-columns
  • grid-auto-rows
  • grid-auto-flow
  • grid
Grid Items 的全部属性
  • grid-column-start
  • grid-column-end
  • grid-row-start
  • grid-row-end
  • grid-column
  • grid-row
  • grid-area
  • justify-self
  • align-self

容器(grid container)的属性

display属性
  • 将元素定义为grid container,并为其内容建立新的网格格式化上下文(grid formatting context),属性值有2个:
    • grid :生成一个块级(block-level)网格
    • inline-grid:生成一个行级(inline-level)网格
.container{
	display: grid | inline-grid;
}
grid-template-columns/grid-template-rows属性
  • 使用以空格分隔的多个值来定义网格的行和列,这些值表示网格轨道(Grid Track) 大小,它们之间的空格表示网格线,属性值为:
.container {
	grid-template-columns: <track-size> ... | <line-name> <track-size> ...;
	grid-template-rows: <track-size> ... | <line-name> <track-size> ...;
}
  • 例:如果没有给网格线命名,轨道值之间仅有空格时,网格线会被自动分配数字名称:
.container{
	grid-template-columns: 40px 50px auto 50px 40px;
	grid-template-rows: 25% 100px auto;
}

示意图

  • 例:给网格线指定确切的命名:
.cotainer{
   grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end];
   grid-template-rows: [row1-start] 25% [row1-end] 100px [third-line] auto [last-line];
}

示意图

  • 注意:一个网格线可以有不止一个名字,例如,这里第2条网格线有两个名字:row1-end 和 row2-start:
.container{
   grid-template-rows: [row1-start] 25% [row1-end row2-start] 25% [row2-end];
}
  • 如果定义中包含重复的部分,可以使用repeat()来简化写法:
.container{
	grid-template-columns: [col-start] 20px [col-start] 20px [col-start] 20px 5%;
}
/*可简写以上代码为如下代码*/
.container{
	grid-template-columns: repeat(3 [col-start] 20px) 5%;
}
  • fr单元允许等分网格容器剩余可用空间来设置网络轨道的大小。例如,下面的代码会将每个网格项设置为网格容器宽度的三分之一:
.container{
	grid-complate-columns: 1fr 1fr 1fr;
}
  • 剩余可用空间是除去所有非灵活网格项之后计算得到的。例:可用空间总量减去50px后。再给fr单元的值3等分:
.container{
	grid-complate-columns: 1fr 50px 1fr 1fr;
}
grid-template-areas属性
  • 通过引用grid-area属性指定的网格区域的名称来定义网络模板,重复网格区域的名称会使内容扩展到这些单元格(不理解可先看示例代码)。这个语法本身可看做网格的可视化结构。属性值只有3个:
    • <grid-area-name>:由网格项grid-area指定的网格区域名称
    • .点号:代表一个空的网格单元
    • none:不定义网格区域
  • 示例:创建一个四列宽三行高的网格。 整个第一行将由 header 区域组成。 中间一行将由两个 main 区域、一个空单元格和一个 sidebar 区域组成。 最后一行由footer区域组成
.item-a{
	grid-area: header;
}
.item-b{
	grid-area: main;
}
.item-c {
	grid-area: sidebar;
}
.item-d {
	grid-area: footer;
}
.container{
	grid-template-columns: 50px 50px 50px 50px;
	grid-template-rows: auto;
	grid-template-areas:
		"header header header header"
		"main main . sidebar"
		"footer footer footer footer";
}

示意图

  • 声明中的每一行都需要有相同数量的单元格,可以使用任意数量的.来声明单个空单元格。需要注意的是,不是在用这个语法命名单元格,而是在命名区域,使用这个语法时,实际上区域两端的网格线是自动命名的。 比如,如果网格区域的名称是foo,那么区域的起始的行网格线和列网格线名称是 foo-start,并且区域终点的行网格线和列网格线名称是 foo-end。 这意味着某些网格线可能有多个名称,比如上面的例子中最左边的一条网格线有三个名字:header-start,main-start 和 footer-start。
grid-template属性
  • 在单个声明中定义grid-template-columnsgrid-template-rowsgrid-template-areas的简写,例:
.container{
	grid-template-rows: [row1-start] 25px [row1-end row2-start] 25px [row2-end];
  	grid-template-columns: auto 50px auto;
  	grid-template-areas: 
    	"header header header" 
    	"footer footer footer";
}
/*以上代码可简写为以下代码*/
.container{
	grid-template:
		[row1-start] "header header header" 25px [row1-end];
		[row2-start] "footer footer footer" 25px [row2-end];
		/ auto 50px auto;
}
  • 注意:由于 grid-template 不会重置隐式网格属性(grid-auto-columnsgrid-auto-rowsgrid-auto-flow),而这可能在大多数情况是必要的,因此建议使用grid属性来代替grid-template
grid-column-gap/grid-row-gap属性
  • 指定网格线的大小,可以想象为设置列/行之间的间距宽度,属性值为<line-size>,一个长度值,例:
.container{
	grid-template-columns: 100px 50px 100px;
	grid-template-rows: 80px auto 80px;
	grid-column-gap: 10px;
	grid-rows-gap: 15px;
}
  • 效果图(注意:只能在列/行之间创建缝隙,而不是在外部边缘创建):
    效果图
gird-gap属性
  • grid-row-gapgrid-column-gap 的简写
.container{
	grid-gap: <grid-row-gap> <grid-column-gap>;
}
  • 如果属性值只设置了一个值,则 grid-row-gap与 grid-column-gap 被设置为相同的值
justify-items/align-items属性
  • 沿着行/列轴对齐网格内的内容,适用于容器内的所有的grid items,属性值有四个:
    • start:内容与网格区域的左端/顶端对齐
      行
    • end:内容内容与网格区域的右端/底部对齐
      行
    • center:内容位于网格区域的中间/垂直中心位置
      行
    • stretch(默认值):内容宽度/高度占据整个网格区域空间
      行
place-items属性
  • 设置 align-itemsjustify-items 的简写
.container{
	place-items: <align-items> <justify-items>;
}
  • 如果省略第二个值,则将第一个值同时分配给这两个属性
justify-content/align-content属性
  • 如果所有的grid items都使用像px这样的非弹性单位来设置大小,则可能出现网格总大小小于其容器的大小,此时,可以设置网格容器的内的网格对齐方式,沿着行/列轴对齐网格,属性值有7个:
    • start:网格与网格容器的左边/顶部对齐
      行
    • end:网格与网格容器的右边/底部对齐
      行
    • center:网格与网格容器的中间对齐
      行
    • stretch:调整grid item 的大小,让宽度/高度填充整个网格容器
      行
    • space-around:在 grid item 之间设置均等宽度/高度的空白间隙,其外边缘间隙大小为中间空白间隙宽度的一半
      行
    • space-between:在 grid item 之间设置均等宽度/高度空白间隙,其外边缘无间隙
      行
    • space-evenly:在每个 grid item 之间设置均等宽度/高度的空白间隙,包括外边缘
      行
place-content属性
  • 设置 align-contentjustify-content 的简写
.container{
	place-content: <align-content> <justify-content>;
}
  • 如果省略第二个值,则将第一个值同时分配给这两个属性
grid-auto-columns/grid-auto-rows属性
  • 指定自动生成的网格轨道(又名隐式网格轨道)的大小。隐式网格轨道在你显式的定位超出指定网格范围的行或列时被创建,属性值<track-size>可以是一个长度值、一个百分比值或一个自由空间的一部分(fr
  • 创建隐式网格轨道示例代码:
    • 首先创建一个2x2的网格
      .container {
      	grid-template-columns: 60px 60px;
      	grid-template-rows: 90px 90px
      }
      
      示意图
    • 然后使用grid-columngrid-row来定位你的网格项目
    .item-a{
    	grid-column: 1 / 2;
    	grid-row: 2 / 3;
    }
    .item-b{
    	grid-column: 5 / 6;
    	grid-row: 2 / 3;
    }
    
    示意图
    • 这里指定 .item-b开始于列网格线 5 并结束于在列网格线 6,但并未定义列网格线 5 或 6。因为引用了不存在的网格线,宽度为0的隐式轨道就会被创建用于填补间隙。可以使用 grid-auto-columnsgrid-auto-rows属性来指定这些隐式轨道的宽度:
    .container{
    	grid-auto-columns: 60px;
    }
    
    示意图
grid-auto-flow属性
  • 如果有一些没有明确放置在网格上的grid item,自动放置算法会自动放置这些网格项,该属性则用于控制自动布局算法的工作方式,属性值有3个:
    • row(默认值):告诉自动布局算法依次填充每行,根据需要添加新行
    • column:告诉自动布局算法依次填充每列,根据需要添加新列
    • dense:告诉自动布局算法,如果后面出现较小的 grid item,则尝试填充在网格中较早的空缺
  • 注意:dense 只会更改网格项的可视顺序,并可能导致它们出现乱序,这对可访问性不利
  • 例,有如下html:
<section class="container">
	<div class="item-a">item-a</div>
	<div class="item-b">item-b</div>
	<div class="item-c">item-c</div>
	<div class="item-d">item-d</div>
	<div class="item-e">item-e</div>
</section>

定义一个有5列2行的网格,并将grid-auto-flow设置为row

.container {
	display: grid;
	grid-template-columns: 60px 60px 60px 60px 60px;
	grid-template-rows: 30px 30px;
	grid-auto-flow: row;
}

把 grid item 放在网格上时,只设置其中两个固定的位置:

.item-a {
	grid-column: 1;
	grid-row: 1 / 3;
}
.item-e {
	grid-column: 5;
	grid-row: 1 / 3;
}
  • 因为将grid-auto-flow设置为row,所以以上代码效果图如下所示:
    示意图
  • 如果将grid-auto-flow设置为column,代码与示意图如下:
.container {
	display: grid;
	grid-template-columns: 60px 60px 60px 60px 60px;
	grid-template-rows: 30px 30px;
	grid-auto-flow: column;
}

示意图

grid属性
  • 在单个属性中设置所有以下属性的简写:grid-template-rowsgrid-template-columnsgrid-template-areasgrid-auto-rowsgrid-auto-columnsgrid-auto-flow(注意:只能在单个网格声明中指定显式或隐式网格属性)。属性值:
    • none:将所有子属性设置为其初始值
    • <grid-template>:与grid-template 简写的工作方式相同
    • <grid-auto-flow> [<grid-auto-rows> [ / <grid-auto-columns>] ] :接受所有与grid-auto-flowgrid-auto-rowsgrid-auto-columns相同的值。 如果省略grid-auto-columns,则将其设置为为grid-auto-rows指定的值。 如果两者都被省略,则它们被设置为它们的初始值
  • 例,以下代码写法等价:
.container {
	grid: 200px auto / 1fr auto 1fr;
}
.container {
	grid-template-rows: 200px auto;
	grid-template-columns: 1fr auto 1fr;
	grid-template-areas: none;
}
  • 例,以下代码写法等价:
.container {
	grid: column 1fr / auto;
}
.container {
	grid-auto-flow: column;
	grid-auto-rows: 1fr;
	grid-auto-columns: auto;
}
  • 也可用使用一个更复杂但相当方便的语法来一次设置所有内容。可以指定 grid-template-areasgrid-template-rows以及 grid-template-columns,并将所有其他子属性设置为其初始值。
  • 例,在网格区域内,指定网格线名称和内联轨道大小:
.container {
	grid: 
	[row1-start] "header header header" 1fr [row1-end]
 	[row2-start] "footer footer footer" 25px [row2-end]
    / auto 50px auto;
}

以上代码等价于:

.container {
	grid-template-areas: 
		"header header header"
		"footer footer footer";
	grid-template-rows: [row1-start] 1fr [row1-end row2-start] 25px [row2-end];
	grid-template-columns: auto 50px auto;    
}

项目(Grid Items)的属性

grid-column-start/grid-column-end/grid-row-start /grid-row-end属性
  • 使用特定的网格线确定 grid item 在网格内的位置。grid-column-start/grid-row-start属性表示grid item的网格线的起始位置,grid-column-end/grid-row-end属性表示网格项的网格线的终止位置,属性值有:
    • <line>:可以是一个数字来指代相应编号的网格线,也可以使用名称指代相应命名的网格线
    • span<number>:网格项将跨越指定数量的网格轨道
    • span<name>:网格项将跨越一些轨道,直到碰到指定命名的网格线
    • auto:自动布局,或者自动跨越,或者跨越一个默认的轨道
  • 举例:
.item-a{
	grid-column-start: 2;
	grid-column-end: five;
	grid-row-start: row1-start;
	grid-row-end: 3;
}

示意图

.item-b{
	grid-column-start: 1;
	grid-column-end: span col4-start;
	grid-row-start: 2;
	grid-row-end: span 2;
}

示意图

  • 如果没有声明 grid-column-end / grid-row-end,默认情况下,该网格项将跨越1个轨道
  • 网格项可以相互重叠,可以使用z-index来控制它们的堆叠顺序
grid-column/grid-row属性
  • grid-column-start+ grid-column-end,和grid-row-start+ grid-row-end 的简写形式,属性值为<start-line> / <end-line>,每个值的用法都和属性分开写时的用法一样,例:
.item-c{
grid-column: 3 / span 2;
grid-row: third-line / 4;
}

示意图

  • 如果没有指定结束行值,则该网格项默认跨越1个轨道
grid-area属性
  • 给 grid item 进行命名以便于使用 grid-template-areas属性创建模板时来进行引用。另外也可以做为 grid-row-start+ grid-column-start+ grid-row-end+ grid-column-end 的简写形式。属性值有:
    • <name>:对区域的命名
    • <row-start> / <column-start>/<row-end> / <column-end>:可以是数字,也可以是网格线的名字
  • 举例:
/*给一个网格项命名*/
item-d{
	grid-area: header;
}
/*简写*/
.item-d{
	grid-area: 1 / col4-start / last-line / 6;
}

示意图

justify-self/align-self属性
  • 沿着行/列轴对齐grid item 里的内容。此属性对单个网格项内的内容生效,属性值:
    • start:将内容对齐到网格区域的左端/顶部
      示意图
      示意图
    • end:将内容对齐到网格区域的右端/底部
      示意图
      示意图
    • center:将内容对齐到网格区域的中间
      示意图
      示意图
    • stretch(默认值):填充网格区域的宽度/高度
      示意图
  • 要为网格中的所有grid items 设置对齐方式,也可以通过justify-items /align-items属性在网格容器上设置此行为
place-self属性
  • 是设置 align-selfjustify-self 的简写形式
.container{
	place-content: <align-self> <justify-self> | auto;
}
  • 如果省略第二个值,则将第一个值同时分配给这两个属性
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐