CSS Grid 网格布局

417 阅读7分钟

网格布局

CSS 网格布局将一个页面划分为几个主要区域,以及定义这些区域的大小、位置、层次等关系

基本概念

网格容器

通过在元素上声明  display:grid  或  display:inline-grid  来创建一个网格容器。这个元素的所有直系子元素将成为网格元素

例如下面,类名 containerdiv元素就是网格容器,内部的 3 个div就是容器元素

.container {
  display: grid;
}
<div class="container">
  <div class="item">1</div>
  <div class="item">2</div>
  <div class="item">3</div>
</div>

网格轨道

通过  grid-template-columns  和  grid-template-rows  属性来定义网格中的行和列. 一个网格轨道就是网格中任意两条线之间的空间,图中红色的就是行轨道

image.png

<div class="container">
  <div class="item item1">1</div>
  <div class="item item1">2</div>
  <div class="item item1">3</div>
  <div class="item">4</div>
  <div class="item">5</div>
  <div class="item">6</div>
  <div class="item">7</div>
  <div class="item">8</div>
  <div class="item">9</div>
</div>
.container {
  display: grid;
  grid-template-columns: 200px 200px 200px;
  grid-template-rows: 50px 50px 50px;
  border: 1px solid #ff8c8c;
}

.item {
  box-sizing: border-box;
  color: #fff;
  border: 1px solid grey;
}

.item1 {
  background-color: red;
}

网格线

划分网格结构的线就是网格线,水平网格线划分出行,垂直网格线划分出列。

image.png

网格单元

网格单元是在一个网格元素中最小的单位。

网格区域

网格区域就是网格上的一个矩形区域,由一个或多个网格单元组成。

网格间距

在两个网格单元之间的  网格横向间距  或  网格纵向间距  可使用  grid-column-gap  和  grid-row-gap  属性来创建,或者直接使用两个合并的缩写形式  grid-gap

属性

grid-template-columns | grid-template-rows

grid-template-columns用于设置网格的列数和宽度,grid-template-rows用于设置网格的行数和高度

绝对值

三行三列宽高都是 100px 的网格

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

百分比

grid-template-columns: 50% 50%;
grid-template-rows: 50% 50%;

repeat

repeat()接受两个参数,第一个是重复的次数,第二个是重复的值

grid-template-columns: repeat(3, 33.3%);
grid-template-rows: repeat(3, 33.3%);

auto-fit

单元格大小固定,容器大小不确定。auto-fit可以使每一行尽可能容纳更多的单元格。

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

fr

fr 单位是“fractional”的缩写,是 CSS 网格布局中引入的长度单位。它代表网格容器中可用空间的一部分。
下面的例子中设置两列宽度为1fr2fr,将可用空间分为 3 分,分别占 1 份和 2 份

grid-template-columns: 1fr 2fr;

minmax()

minmax函数允许我们设置网格单元的最小和最大尺寸

grid-template-columns: 1fr minmax(100px, 2fr);

auto

行列的大小由容器的大小和网格元素内容的大小决定。

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

网格线名称

grid-template-columnsgrid-template-rows的属性里面,可以使用方括号,指定每一根网格线的名字,方便引用。

grid-template-columns: [c1] 100px [c2] 100px [c3] auto [c4];
grid-template-rows: [r1] 100px [r2] 100px [r3] auto [r4 cr4];

这里定义了一个三行三列的网格,其中c1、c2、c3、c4是列网格线的名称,r1、r2、r3、r4是行网格线的名称。 网格线可以有多个名字,例如[r4 cr4]

row-gap | column-gap | gap

row-gap 用于设置行与行的间距,column-gap设置列与列的间距

row-gap: 20px;
column-gap: 20px;

设置行间距与列间距都为20px

gaprow-gapcolumn-gap的合并简写形式。

gap: <row-gap> <column-gap>;
gap: 20px 20px;

grid-template-areas | grid-area

grid-template-areas用于定义区域,一个区域由单个或多个单元格组成。 grid-area可以对网格单元进行命名。 命名的网格元素可以通过容器的 grid-template-areas 来引用。

.container {
  display: grid;
  grid-template-areas:
    'header header'
    'sidebar main'
    'footer footer';
}

.header {
  grid-area: header;
  background-color: #ef342a;
}
.sidebar {
  grid-area: sidebar;
  background-color: #f68f26;
}
.main {
  grid-area: main;
  background-color: #4ba946;
}
.footer {
  grid-area: footer;
  background-color: #0376c2;
}
<div class="container">
  <div class="header">header</div>
  <div class="sidebar">sidebar</div>
  <div class="main">main</div>
  <div class="footer">footer</div>
</div>

image.png

如果有区域不利用,可以使用.来表示

.container {
  display: grid;
  grid-template-areas:
    'header header header'
    'sidebar . main'
    'footer footer footer';
}

image.png

grid-auto-flow

grid-auto-flow设置网格中的元素排列方式。

```css
grid-auto-flow: row|column|dense|row dense|column dense;
grid-auto-flow: column;

image.png

grid-auto-flow: row;

image.png

grid-auto-flow: row dense;

row dense,表示先行后列,并且尽可能紧密填满,尽量不出现空格

image.png

grid-auto-flow: column dense;

column dense,表示先列后行,并且尽量填满空格

image.png

justify-items | align-items | place-items

justify-items设置单元格的水平位置,align-items设置单元格的垂直位置。控制网格项目内容的对齐方式。

属性值

  • start:对齐单元格的起始边缘。
  • end:对齐单元格的结束边缘。
  • center:单元格内部居中。
  • stretch:拉伸,占满单元格的整个宽度(默认值)。
.container{
  justify-items: center;
}

image.png

.container{
  align-items: end;
}

image.png

place-itemsjustify-itemsalign-items的合并简写形式。

place-items: <align-items> <justify-items>;
.container{
  place-items: end end;
}

justify-content | align-content | place-content

justify-content设置网格在网格容器内的水平对齐方式,align-content设置置网格在网格容器内的垂直对齐方式。控制网格行列在容器内的对齐方式。

属性值

  • start: 对齐容器的起始边框
  • end: 对齐容器的结束边框
  • center: 容器内部居中
  • stretch: 项目大小没有指定时,拉伸占据整个网格容器
  • space-around: 每个项目两侧的间隔相等。所以,项目之间的间隔比项目与容器边框的间隔大一倍
  • space-between: 项目与项目的间隔相等,项目与容器边框之间没有间隔
  • space-evenly: 项目与项目的间隔相等,项目与容器边框之间也是同样长度的间隔
.container{
  justify-content: center;
  align-content: end;
}

image.png

place-contentjustify-contentalign-content的合并简写形式。

place-content: <align-content> <justify-content>;
.container{
  place-content: end end;
}

justify-self

justify-self设置内容在单元格中的水平对齐位置,align-self设置内容在单元格中的垂直对齐位置.会覆盖单个项目的justify-items

  • start:对齐单元格的起始边缘
  • end:对齐单元格的结束边缘
  • center:单元格内部居中
  • stretch:拉伸,占满单元格的整个宽度(默认值)
.container{
  justify-items: start;
  align-items:start;
}
.item1{
   justify-self: end;
   align-self:end;
}

place-selfjustify-selfalign-self的合并简写形式。

place-self: <align-self> <justify-self>;
.container{
  place-self: end end;
}

grid-auto-columns | grid-auto-rows

当我们设置的网格不足以放下所有的网格项时,浏览器会自动生成多余的网格,以便放置项目,这些多出来的行的高度是auto的,grid-auto-columnsgrid-auto-rows就是用来设置这些多余的网格的列宽和行高。

.container{
  display: grid;
  grid-template-columns: 100px 100px ;
  grid-template-rows: 100px 100px;
  grid-auto-columns: 50px
  grid-auto-rows: 50px; 
}

如下图新增的行高列宽为50px

image.png

grid-column-start | grid-column-end | grid-row-start | grid-row-end

允许指定网格项在网格容器内的起始位置和结束位置,具体方法就是指定项目的四个边框,分别定位在哪根网格线。

  • grid-column-start:左边框所在的垂直网格线
  • grid-column-end:右边框所在的垂直网格线
  • grid-row-start:上边框所在的水平网格线
  • grid-row-end:下边框所在的水平网格线
.item-1 {
  grid-column-start: 2;
  grid-column-end: 4;
  grid-row-start: 1;
  grid-row-end: 3;
}

指定项目1的左边框是第二根垂直网格线,右边框是右边第四根垂直网格线,上边框是第一个水平网格线,下边框是第三根水平网格线

image.png

除了指定为第几个网格线,还可以指定为网格线的名字。

.item-1 {
  grid-column-start: header-start;
  grid-column-end: header-end;
}

还可以使用 span关键字,表示跨越网格。

.item-1 {
  grid-column-start: span 2;
}

项目1的左边框距离右边框跨越2个网格

image.png

grid-area属性还可用作grid-row-startgrid-column-startgrid-row-endgrid-column-end的合并简写形式,直接指定项目的位置。

grid-area: <row-start> / <column-start> / <row-end> / <column-end>;
.item-1 {
  grid-area: 1 / 1 / 3 / 3;
}