Grid布局的那些事儿!

前端开发
2019年08月31日
0

网格布局 Grid Layout

网格布局是一种二维的布局模式。可用于页面主要的区域布局或小型组件。

术语

Grid

通过设置dispaly: grid;或者display: inline-grid;把一个容器变成一个Grid容器,那么它的直系子元素则是Grid元素。

网格线 Grid lines

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

css
.wrapper { display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 60px); }
html
<div class="wrapper"> <div class="item item1"></div> <div class="item item2"></div> <div class="item item3"></div> <div class="item item4"></div> <div class="item item5"></div> <div class="item item6"></div> <div class="item item7"></div> <div class="item item8"></div> <div class="item item9"></div> </div>

上面的例子三行三列的网格,它有4条行线(row-line)和和4条列线(col-line)。

在从左到右的语言中,线编号如下图所示(线编号遵循文档的写入模式)。

grid1.jpeg

网格轨道 Grid tracks

两条网格线之间的空间叫做网格轨道,同样是上面的例子,会有三个行轨道和三个列轨道。如下图所示:

grid2.jpeg

网格单元格 Grid cell

两条行网格线与两条列网络线之间的空间叫做单元格,这与表格里面的单元格定义是一致的。

网格单元格是网格布局中的最小单元。

grid3.jpeg

网格区域 Grid areas

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

grid4.jpeg

网格间隙 Gutters

网格间隙指两个单元格之间的间距。

网格轴 Grid Axis

网格中有两个轴,横轴(行轴)和纵轴(列轴)。沿着这些轴可以对项目进行行对齐和列对齐。

这些轴的物理方向会根据文档的写入模式writing-mode而改变。

属性

grid-template-columns

grid-template-columns可以用来定义列网格线的名称和网格轨道的尺寸大小。

语法:

css
grid-template-columns: 100px 1fr; grid-template-columns: [linename] 100px; grid-template-columns: [linename1] 100px [linename2 linename3]; grid-template-columns: minmax(100px, 1fr); grid-template-columns: fit-content(40%); grid-template-columns: repeat(3, 200px); grid-template-columns: 200px repeat(auto-fill, 100px) 300px; grid-template-columns: minmax(100px, max-content) repeat(auto-fill, 200px) 20%; grid-template-columns: [linename1] 100px [linename2] repeat(auto-fit, [linename3 linename4] 300px) 100px; grid-template-columns: [linename1 linename2] 100px repeat(auto-fit, [linename1] 300px) [linename3];
  • [linename]:表示该网格线的自定义名称;
  • repeat():表示重复定义多个网格轨道;接受2个参数,第一个参数可以是正整数、auto-fill(自动计算剩余的空间可分布多少个轨道,如果容器的宽度足够大,会生成空的轨道项用于填充)或者auto-fit(与auto-fill相似,但是不会生成空的轨道项);第二个参数则是尺寸值。
  • minmax(min, max):定义最小尺寸与最大尺寸。如果max值小于min值,该轨道的尺寸则会被视为min值
  • max-content:是一个用来表示以网格项的最大的内容来占据网格轨道的关键字(只能当max参数传入)。
  • min-content:是一个用来表示以网格项的最大的最小内容来占据网格轨道的关键字(只能当max参数传入)。

grid5.jpeg

auto-fill

grid6.jpeg

auto-fit

css
.wrapper { display: grid; grid-template-columns: [myFirstLine] 100px [mySecondLine] 150px [myThirdLine] 200px [myLastLine]; } .item8 { grid-column-start: myFirstLine; grid-column-end: myThirdLine; background: blue; }
html
<div class="wrapper"> <div class="item item1">item 1</div> <div class="item item2">item 2</div> <div class="item item3">item 3</div> <div class="item item4">item 4</div> <div class="item item5">item 5</div> <div class="item item6">item 6</div> <div class="item item7">item 7</div> <div class="item item8">item 8</div> <div class="item item9">item 9</div> </div>

grid7.jpeg

grid-template-rows

grid-template-rows可以用来定义行网格线的名称和网格轨道的尺寸大小。(设置方式与grid-template-columns一样)

grid-template-areas

grid-template-areas这个属性非常有意思,可以让我们很直观地进行布局。

css
.wrapper { display: grid; grid-template-columns: repeat(9, 50px); grid-auto-rows: 100px; grid-template-areas: "hd hd hd hd hd hd hd hd hd" "sd sd sd main main main main main main" "sd sd sd ft ft ft ft ft ft" ; } .header { grid-area: hd; background-color: lightblue; } .side { grid-area: sd; background-color: indianred; } .main { grid-area: main; background-color: gray; } .footer { grid-area: ft; background-color: black; }
html
<div class="wrapper"> <div class="item header">header</div> <div class="item side">side</div> <div class="item main">main</div> <div class="item footer">footer</div> </div>

grid8.jpeg

也可以通过点(.)的方式来占位留空。还是上面的例子,其他内容不变。

css
.wrapper { grid-template-areas: "hd hd hd hd hd hd hd hd hd" "sd sd sd main main main main main main" ". . . ft ft ft ft ft ft" ; }

grid9.jpeg

grid-template

grid-templategrid-template-areasgrid-template-rowsgrid-template-columns的简写形式。

语法:

css
/* 为 grid-template-rows / grid-template-columns */ grid-template: 100px 1fr / 50px 1fr; grid-template: auto 1fr / auto 1fr auto; grid-template: [linename1] 100px / [linename2] 30% [linename3] 70%; grid-template: fit-content(100px) / fit-content(40%); /* 为 grid-template-areas grid-template-rows / grid-template-column */ grid-template: "a a a" "b b b" ; grid-template: "a a a" 20% "b b b" auto ; grid-template: [linename1] "a a a" [linename2] [linename3] "b b b" 1fr [linename4] / auto 1fr auto ;
css
.wrapper { display: grid; grid-template: "hd hd" 100px "sd main" 1fr "sd ft" 100px / 80px 1fr; ; width: 300px; height: 500px; }
html
<div class="wrapper"> <div class="item header">header</div> <div class="item side">side</div> <div class="item main">main</div> <div class="item footer">footer</div> </div>

grid10.jpeg

grid-auto-columns

grid-auto-columns隐式地定义了列轨道的尺寸。

语法:

css
/* Keyword values */ grid-auto-columns: min-content; grid-auto-columns: max-content; grid-auto-columns: auto; /* <length> values */ grid-auto-columns: 100px; grid-auto-columns: 20cm; grid-auto-columns: 50vmax; /* <percentage> values */ grid-auto-columns: 10%; grid-auto-columns: 33.3%; /* <flex> values */ grid-auto-columns: 0.5fr; grid-auto-columns: 3fr; /* minmax() values */ grid-auto-columns: minmax(100px, auto); grid-auto-columns: minmax(max-content, 2fr); grid-auto-columns: minmax(20%, 80vmax); /* fit-content() values */ grid-auto-columns: fit-content(400px); grid-auto-columns: fit-content(5cm); grid-auto-columns: fit-content(20%); /* multiple track-size values */ grid-auto-columns: min-content max-content auto; grid-auto-columns: 100px 150px 390px; grid-auto-columns: 10% 33.3%; grid-auto-columns: 0.5fr 3fr 1fr; grid-auto-columns: minmax(100px, auto) minmax(max-content, 2fr) minmax(20%, 80vmax); grid-auto-columns: 100px minmax(100px, auto) 10% 0.5fr fit-content(400px);

grid-auto-rows

grid-auto-rows隐式地定义了行轨道的尺寸。

css
.wrapper { display: grid; grid-template-areas: "a a a"; grid-auto-columns: 100px 50px 200px; grid-auto-rows: 60px 100px 50px; }
html
<div class="wrapper"> <div class="item item1">这里是Item 1</div> <div class="item item2">item 2</div> <div class="item item3">item 3</div> <div class="item item4">item 4</div> <div class="item item5">item 5</div> <div class="item item6">item 6</div> <div class="item item7">item 7</div> <div class="item item8">item 8</div> <div class="item item9">item 9</div> </div>

grid11.jpeg

grid-auto-flow

grid-auto-flow指定网格元素则如何排列。

该属性有两种形式:

  • 单个关键字:rowcolumndense中的一种;
  • 两个关键字:row densecolumn dense

row关键字指定元素逐行填充;

column关键字指定元素逐列填充;

dense关键字指定元素使用“紧凑”的堆积算法,如果后面出现了稍微小的元素,则会试图填充网格中前面的空白部分。这样做可能会导致元素出现的次序被打乱。

grid-column-gap

指定两个相邻的列单元格之间的间隙。

grid-column-gap: 10px;

grid-row-gap

指定两个相邻的列单元格之间的间隙。

grid-row-gap: 2em;

grid-gap

grid-row-gapgrid-column-gap的缩写形式。

grid-gap: 2vmin 20%;

grid

grid是一个缩写形式。可以用以设置以下属性:

  • grid-template-rowsgrid-template-columnsgrid-template-areas;
  • grid-auto-rowsgrid-auto-columnsgrid-auto-flow

注意:grid只能定义其中一种。

定位

  • grid-column-start: 定义grid元素从哪条列线开始排列
  • grid-column-end: 定义grid元素到哪条列线结束
  • grid-row-start: 定义grid元素从哪条行线开始排列
  • grid-row-end: 定义grid元素到哪条行线结束
  • grid-column: grid-column-start / grid-column-end 的简写
  • grid-row: grid-row-start / grid-row-end 的简写
  • grid-area: grid-row-start / grid-column-start / grid-row-end / grid-column-end 的简写
css
.wrapper { display: grid; grid-template-columns: repeat(3, 1fr); grid-auto-rows: 100px 1fr 150px; } .item1 { grid-column-start: 1; grid-column-end: 3; grid-row-start: 1; } .item2 { grid-column-start: 4; grid-row: 1 / 3; } .item3 { grid-column-start: 5; grid-column-end: span 2; grid-row: 2 / span 2; } .item6 { grid-area: 3 / 2 / 4 / span 3; }
html
<div class="wrapper"> <div class="item item1">这里是Item 1</div> <div class="item item2">item 2</div> <div class="item item3">item 3</div> <div class="item item4">item 4</div> <div class="item item5">item 5</div> <div class="item item6">item 6</div> <div class="item item7">item 7</div> <div class="item item8">item 8</div> <div class="item item9">item 9</div> </div>

grid12.jpeg

对齐属性

justify-items、justify-self

justify-items批量定义元素在列线上的对齐方式,justify-self则是定义指定的元素在列线上的对齐方式。

可接受的值如下:

  • auto
  • normal
  • start
  • end
  • center
  • stretch
  • baseline
  • first baseline
  • last baseline
css
.wrapper { display: grid; grid-template-columns: repeat(2, 1fr); grid-template-rows: 100px 100px; justify-items: stretch; /* 拉伸对齐 */ } .item2 { justify-self: end; } .item3 { justify-self: center; } .item4 { justify-self: start; }
html
<div class="wrapper"> <div class="item item1">item 1</div> <div class="item item2">item 2</div> <div class="item item3">item 3 item 3</div> <div class="item item4">item 4</div> </div>

grid13.jpeg

align-items、align-self

align-items批量定义元素在行线上的对齐方式,align-self则是定义指定的元素在行线上的对齐方式。

css
.wrapper { display: grid; grid-template-columns: repeat(2, 1fr); grid-template-rows: 100px 100px; align-items: stretch; } .item2 { align-self: end; } .item3 { align-self: center; } .item4 { align-self: start; }

grid14.jpeg

justify-content

定义所有元素整体在列轴上的对齐方式(类似flex里面的justify-content)

align-content

定义所有元素整体在行轴上的对齐方式(类似flex里面的justify-content)

css
.wrapper { display: grid; grid-template-columns: 100px 200px; grid-template-rows: 100px 200px; justify-content: space-around; align-content: space-between; }

grid15.jpeg