Grid Layout 翻译过来是[网格布局]的意思,它是一个二维系统,包含了行(row)与列(column)以及间距(gap)。下图能够很好的说明这一点(图片来自mdn):
工作中写移动端页面的朋友对 Flex 布局肯定不陌生,有些人可能更极端一点,直接 Flex 一把梭。那 Grid 和 Flex 有什么区别呢?我们仍然可以用一张图片进行举例说明:
在上图中,我们可以使用 Grid 来搭建页面的整体结构;而使用 Flex 控制 Grid 中的单个区域,例如顶部导航栏中的具体内容。
Grid vs Flex 总结
总的来说,Grid 擅长搭建布局结构,而 Flex 则擅长处理元素的流向。
首先我们需要将容器的 display 属性设置为 grid,然后使用下列 CSS 属性来控制其中的行与列:
grid-template-columns
用来划分列数grid-template-rows
用来划分行数https://codepen.io/JingW/embed/RwNjowB?height=826&theme-id=default&default-tab=result
通过上面 demo 你会发现一个问题,如果一行有 3 列,我们就需要定义 3 列各自的宽,那如果有 10 列,20 列呢?难道都需要一个个设置,岂不是太麻烦了?所以重复设置的需求应运而生。我们可以使用 repeat
统一设置值,第一个参数为重复数量,第二个参数是重复值。下面是两个示例:
https://codepen.io/JingW/embed/abzVQmR?default-tab=html%2Cresult
我们还可以像 Flex 布局的 flex: 1
那样,给布局中的元素设置比例。在 Grid 中,我们使用 fr
这个单位来设置元素在空间中所占的比例。
https://codepen.io/JingW/embed/oNgoQEK?default-tab=html%2Cresult
grid**-tempalte
是 grid**-template-rows
、grid**-template-columns
、grid**-template-areas
的三个属性的简写。
下面是使用 **grid**-template
同时声明 **grid**-template-rows、**grid**-template-columns
。
**grid-template**: 100**px** 1**fr** / 50**px** 1**fr**;
下面是使用 **grid**-template
定义 **grid**-template-areas
,有关 **grid**-template-areas
的使用方法会在下面介绍:
grid-template:
'header . .'
'. main .'
'footer footer .';
https://codepen.io/JingW/embed/yLyPQjj?default-tab=html%2Cresult
使用 minmax 方法可以设置取值范围。下面行高在 最小100px ~ 最大1fr
间取值:
https://codepen.io/JingW/embed/dyPZQro?default-tab=html%2Cresult
https://codepen.io/JingW/embed/ExabOqB?default-tab=html%2Cresult
https://codepen.io/JingW/embed/QWwOzLr?default-tab=html%2Cresult
使用 gap 规则可以一次定义行、列间距,如果间距一样可以只设置一个值:
https://codepen.io/JingW/embed/zYxPyOQ?default-tab=html%2Cresult
通过 grid-template-rows 和 grid-template-columns 定义网格时,网格线可以被命名。网格线名称也可以设置网格项目位置
分配网格线名称必须用方括号[网格线名称],然后后面紧跟网格轨道的尺寸值。定义网格线名称时需要避免使用规范中出现的关键词,以免导致混乱。
grid-template-rows: [row-1-start] 1fr [row-2-start] 1fr [row-2-end];
grid-template-columns: [col-1-start] 1fr [col-2-start] 1fr [col-3-start] 1fr [col-3-end];
可以在方括号中添加多个名称来命名网格线名称,使用多外名称命名网格线名称时,名称间要用空格隔开。每一个网格线的名称可以用来定位网格项目的位置。
使用网格线名称设置网格项目位置和使用网格线号码设置网格项目位置类似,引用网格线名称的时候不应该带方括号
使用 repeat()函数可以给网格线分配相同的名称。这可以节省一定的时间。
grid-template-rows: repeat(3, [row-start] 1fr [row-end]);
grid-template-columns: repeat(3, [col-start] 1fr [col-end]);
使用 repeat()函数可以给网格线命名,这也导致多个网格线具有相同的网格线名称。相同网格线名称指定网格线的位置和名称,也且会自动在网格线名称后面添加对应的数字,使其网格线名称也是唯一的标识符。
使用相同的网格线名称可以设置网格项目的位置。网格线的名称和数字之间需要用空格分开。
grid-row: row-start 2 / row-end 3;
grid-column: col-start / col-start 3;
像网格线名称一样,网格区域的名称可以使用 grid-template-areas 属性来命名。引用网格区域名称也可以设置网格项目位置。
grid-template-areas: 'header header' 'content sidebar' 'footer footer';
grid-template-rows: 150px 1fr 100px;
grid-template-columns: 1fr 200px;
设置网格区域的名称应该放置在单引号或双引号内,每个名称由一个空格符分开。网格区域的名称,每组(单引号或双引号内的网格区域名称)定义了网格的一行,每个网格区域名称定义网格的一列。
[注意]grid-template-areas: “header header” “content sidebar” “footer footer”;不可以简写为 grid-template-areas: “header” “content sidebar” “footer”;
grid-row-start、grid-row-end、grid-column-start 和 grid-column-end 以及简写的 grid-row、grid-column、grid-area 都可以引用网格区域名称,用来设置网格项目位置。
选项 | 说明 |
---|---|
grid-row-start | 行开始栅格线 |
grid-row-end | 行结束栅格线 |
grid-column-start | 列开始栅格线 |
grid-column-end | 列结束栅格线 |
通过设置具体的第几条栅格线来设置区域位置,设置的数值可以是正数和负数:
https://codepen.io/JingW/embed/oNgomod?default-tab=html%2Cresult
https://codepen.io/JingW/embed/mdyqvgZ?default-tab=html%2Cresult
使用 span
可以设置移动单元格数量,数值只能为正数。
grid***-end
表示 **grid***-end
栅格线是从 **grid***-start
移动几个单元格grid***-start
表示 **grid***-start
栅格线是从 **grid***-end
移动几个单元格https://codepen.io/JingW/embed/dyPZrOE?default-tab=html%2Cresult
可以使用 **grid**-row
设置行开始栅格线,使用 **grid**-column
设置结束栅格线。
上例中的居中对齐元素,可以使用以下简写的方式声明(推荐)。
grid-row: 2/3;
grid-column: 2/3;
https://codepen.io/JingW/embed/bGNabrX?default-tab=html%2Cresult
**grid**-area
更加简洁是同时对 **grid**-row
与 **grid**-column
属性的组合声明。
语法结构如下:
grid-row-start/grid-column-start/grid-row-end/grid-column-end
下面是将元素定位在中间的示例:
https://codepen.io/JingW/embed/mdypbBQ?default-tab=html%2Cresult
在容器中设置**grid**-auto-flow
属性可以改变单元流动方式。
选项 | 说明 |
---|---|
column | 按列排序 |
row | 按行排列 |
https://codepen.io/JingW/embed/gObobYm?default-tab=html%2Cresult
当元素在栅格中放不下时,将会发生换行产生留白,使用 grid-auto-flow: row dense; 可以执行填充空白区域操作。
https://codepen.io/JingW/embed/eYmymZX?default-tab=html%2Cresult
可以通过属性方便的定义栅格的对齐方式,可用值包括 start | end | center | stretch | space-between | space-evenly | space-around
。
选项 | 说明 | 对象 |
---|---|---|
align-items | 栅格内所有元素的垂直排列方式 | 栅格容器 |
justify-items | 栅格内所有元素的横向排列方式 | 栅格容器 |
justify-content | 所有栅格在容器中的水平对齐方式,容器有额外空间时 | 栅格容器 |
align-content | 所有栅格在容器中的垂直对齐方式,容器有额外空间时 | 栅格容器 |
align-self | 元素在栅格中垂直对齐方式 | 栅格元素 |
justify-self | 元素在栅格中水平对齐方式 | 栅格元素 |
https://codepen.io/JingW/embed/LYEeERG?default-tab=html%2Cresult
用于控制栅格的对齐方式,语法如下:
place-content: <align-content> <justify-content>;
控制所有元素的对齐方式,语法结构如下:
place-items: <align-items> <justify-items>;
控制单个元素的对齐方式
place-self: <align-self> <justify-self>;