⤴Top⤴

Grid 布局

博客分类: 前端

Grid 布局

Grid 布局

网格布局

网格布局(Grid Layout)是一个基于网格的二维布局系统,而 flexbox 布局则是一维的。

.grid-container {
  display: grid | inline-grid | subgrid;
}

Grid 布局在线 demo 戳这里或者 css-grid-playground 👈👈👈

在网格容器(Grid Container) 上使用 float、clear、vertical-align 会失效。

container 属性

Grid 容器上有下列属性:

属性 描述
grid-template-columns/rows 定义网格的列宽和行高
grid-template-areas 通过引用 grid-area 属性指定的网格区域(Grid Area)名称来定义网格模板
grid-template 以上三者的复合属性
grid-gap grid-row-gap 和 grid-column-gap 的复合属性,定义网格线(grid lines)的大小
justify-items 沿着 行轴线(row axis) 对齐 网格项(grid items) 内的内容
align-items 沿着 列轴线(column axis) 对齐 网格项(grid items) 内的内容
justify-content 设置网格容器内的网格的对齐方式。 此属性沿着 行轴线(row axis) 对齐网格
align-content 设置网格容器内的网格的对齐方式。 此属性沿着 列轴线(column axis) 对齐网格
grid-auto-columns/rows 指定任何自动生成的网格轨道(grid tracks)的大小
grid-auto-flow 控制自动布局算法如何工作
grid 复合属性

grid-template

grid-template 属于 grid-template-rowsgrid-template-columnsgrid-template-areas 的复合属性,可以使用空格分隔的值列表,用来定义网格的列和行以及区域。这些值表示网格轨道(Grid Track)大小,它们之间的空格表示网格线。

grid-template-columns

两条相邻网格线之间的空间,你可以把它们想象成网格的列高行宽:

.item {
  /* <track-size>: 可以是长度值,百分比,或者等份网格容器中可用空间(使用 fr 单位) */
  grid-template-columns: <track-size> ... | <line-name> <track-size> ...;
  grid-template-rows: <track-size> ... | <line-name> <track-size> ...;
}
.grid-container {
  /* 列宽 */
  grid-template-columns: 40px 50px auto 50px 40px;
  /* 行高 */
  grid-template-rows: 25% 100px auto;
}

grid-template-rows-columns

你还可以对网线进行命名,方便引用:

/* 指定网格布局为 3行 x 3列,因此有 4 根垂直网格线和 4 根水平网格线。方括号里面依次是这八根线的名字 */
.container {
  display: grid;
  grid-template-columns: [c1] 100px [c2] 100px [c3] auto [c4];
  grid-template-rows: [r1] 100px [r2] 100px [r3] auto [r4];
}

repeat()

如果你的定义包含多个重复值,则可以使用 repeat() 表示法来简化定义:

.item {
  grid-template-columns: repeat(3, 20px) 5%;
  /* 等同于 */
  grid-template-columns: 20px 20px 20px 5%;
}

fr 可用空间

fr 单元允许你用等分网格容器剩余可用空间来设置网格轨道的大小。剩余可用空间是除去所有非灵活网格项之后计算得到的:

/* 可用空间总量除去 50px,再均分为三等分 */
.item {
  grid-template-columns: 1fr 50px 1fr 1fr;
}

minmax()

minmax() 函数产生一个长度范围,表示长度就在这个范围之中。它接受两个参数,分别为最小值和最大值:

/* minmax(100px, 1fr) 表示列宽不小于 100px,不大于 1fr */
grid-template-columns: 1fr 1fr minmax(100px, 1fr);

grid-template-areas

通过引用 grid-area 属性指定的网格区域(Grid Area)名称来定义网格模板。一个点号(.)代表一个空的网格单元:

/* 创建一个 4 列 3 行的网格。 */
/* 整个顶行将由 header 区域组成。 */
/* 中间一排将由两个 main 区域、一个空网格单元和一个 sidebar 区域组成。 */
/* 整个最后一行将由 footer 区域组成。 */
.item-a {
  grid-area: header;
}
.item-b {
  grid-area: main;
}
.item-c {
  grid-area: sidebar;
}
.item-d {
  grid-area: footer;
}

.grid-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";
}

grid-template-areas

grid-gap

grid-row-gapgrid-column-gap 一样,指定网格线(grid lines)的大小,即设置列/行之间的间距:

.item {
  /* grid-gap 为复合属性 */
  /* 如果 grid-row-gap 没有定义,那么就会被设置为等同于 grid-column-gap 的值 */
  grid-gap: <grid-row-gap> <grid-column-gap>;

  grid-column-gap: <line-size>;
  grid-row-gap: <line-size>;
}

grid-auto-columns

grid-auto-rows 指定任何自动生成的网格轨道(grid tracks)的大小,又称隐式网格轨道。在你明确定位的行或列(通过 grid-template-rows / grid-template-columns)超出定义的网格范围时,隐式网格轨道将被创建:

/* 第五和第六列网格线未被定义 */
.item-a {
  grid-column: 1 / 2;
  grid-row: 2 / 3;
}
.item-b {
  grid-column: 5 / 6;
  grid-row: 2 / 3;
}

.grid-container {
  grid-template-columns: 60px 60px;
  grid-template-rows: 90px 90px
}

grid-tracks

/* 指定这些隐式轨道的大小 */
.grid-container {
  grid-auto-columns: 60px;
}

grid-auto-columns

grid-auto-flow

如果存在一些没有明确放置在网格上的网格项(grid items),自动放置算法会自动放置这些网格项。该属性控制自动布局算法如何工作:

.item {
  grid-auto-flow: row | column | row dense | column dense
}

网格项对齐

justify-items

沿着 行轴线(row axis) 对齐 网格项(grid items) 内的内容:

.item {
  justify-items: start | end | center | stretch;
}
.item {
  justify-items: start;
}

justify-items

align-items

沿着 列轴线(column axis) 对齐 网格项(grid items) 内的内容:

.item {
  align-items: start | end | center | stretch;
}
.item {
  align-items: start;
}

align-items

place-items

属于 align-itemsjustify-items 的复合属性:

.item {
  /* 如果省略第二个值,则浏览器认为与第一个值相等 */
  place-items: <align-items> <justify-items>
  /* 例如 */
  place-items: center;
}

网格容器对齐

justify-content

设置网格容器内的网格的对齐方式。此属性沿着 行轴线(row axis) 对齐网格:

/* 针对网格合计大小可能小于其 网格容器(grid container) 大小 */
.item {
  justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
}
.item {
  justify-content: start;
}

justify-content

align-content

设置网格容器内的网格的对齐方式。 此属性沿着 列轴线(column axis) 对齐网格

/* 针对网格合计大小可能小于其 网格容器(grid container) 大小 */
.item {
  align-content: start | end | center | stretch | space-around | space-between | space-evenly;
}
.item {
  align-content: start;
}

align-content

place-content

属于 align-contentjustify-content 的复合属性:

.item {
  /* 同样如果省略第二个值,则浏览器认为与第一个值相等 */
  place-content: <align-content> <justify-content>
  /* 例如 */
  place-content: center;
}

grid

属于 grid-template-rows、grid-template-columns、grid-template-areas、grid-auto-rows、grid-auto-columns 和 grid-auto-flow 的复合属性:

.container {
  grid: 100px 300px / 3fr 1fr;
}

/* 等价于 */

.container {
  grid-template-rows: 100px 300px;
  grid-template-columns: 3fr 1fr;
}
/* 此用例的grid属性相当于grid-template */
.grid-container {
  grid: [row1-start] "header header header" 1fr [row1-end]
        [row2-start] "footer footer footer" 25px [row2-end]
        / auto 50px auto;
}

/* 等价于 */

.grid-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;
}

item 属性

注意:float,display: inline-block,display: table-cell,vertical-align 和 column-* 属性对网格项无效。

grid-column-start / grid-row-start

通过引用特定网格线(grid lines) 来确定 网格项(grid item) 在网格内的位置。 grid-column-start / grid-row-start 是网格项开始的网格线,grid-column-end / grid-row-end 是网格项结束的网格线:

.item {
  grid-column-start: <number> | <name> | span <number> | span <name> | auto;
  grid-column-end: <number> | <name> | span <number> | span <name> | auto;
  grid-row-start: <number> | <name> | span <number> | span <name> | auto;
  grid-row-end: <number> | <name> | span <number> | span <name> | auto;
}
.item-a {
  grid-column-start: 2;
  grid-column-end: five;
  grid-row-start: row1-start;
  grid-row-end: 3;
}

grid-column-start

/* span 2 表示跨越两个网格,即 grid-row-end 相当于 4 */
.item-b {
  grid-column-start: 1;
  grid-column-end: span col4-start;
  grid-row-start: 2;
  grid-row-end: span 2;
}

grid-column-start span

grid-column-end/grid-row-end 没有定义, 则默认跨越一个网格 👈

grid-column / grid-row

分别为 grid-column-start / grid-column-endgrid-row-start / grid-row-end 的简写形式:

.item {
  grid-column: <start-line> / <end-line> | <start-line> / span <value>;
  grid-row: <start-line> / <end-line> | <start-line> / span <value>;
}
.item-c {
  grid-column: 3 / span 2;
  grid-row: third-line / 4;
}

grid-column

grid-area

grid-area 为网格项提供一个名称,以便可以 被使用网格容器 grid-template-areas 属性创建的模板进行引用,上面已经有栗子了。不过它还有另外一个用法,这个属性可以用作 grid-row-start / grid-column-start / grid-row-end / grid-column-end 的简写:

.item {
  grid-area: <name> | <row-start> / <column-start> / <row-end> / <column-end>;
}
.item-d {
  grid-area: 1 / col4-start / last-line / 6;
}

grid-area

justify-self

沿着 inline(行)轴线对齐网格项( 相反的属性是 align-self ,沿着 block(列)轴线对齐)。此值适用于单个网格项内的内容:

.item {
  justify-self: start | end | center | stretch;
}
.item {
  justify-self: start;
}

justify-self

align-self

沿着 block(列)轴线对齐网格项(grid items)( 相反的属性是 justify-self ,沿着 inline(行)轴线对齐)。此值适用于单个网格项内的内容:

.item {
  align-self: start | end | center | stretch;
}
.item {
  align-self: start;
}

align-self

place-self

属于 align-selfjustify-self 的复合属性:

.item {
  /* 同样如果省略第二个值,则浏览器认为与第一个值相等 */
  place-self: <align-self> <justify-self>
  /* 例如 */
  place-self: center;
}

参考链接

  1. A Complete Guide to Grid By Chris House
  2. CSS Grid VS Flexbox: A Practical Comparison By Danny Markov
  3. CSS Grid 布局这样玩 By 大漠
  4. CSS Grid 布局完全指南 By 渔人码头