3

css3 Grid Layout 表格布局是在css中强大的难以置信的布局模块。它是二维空间的,所以它可以处理行和列

它有些类似于Flexbox,但是又有本质的差别。Flexbox同样很强大,但是它主要是一维空间的。Flexbox可以处理列或者行,Grid可以同时处理两者。

综合运用它们,可以帮助我们在css中实现在之前无法想象的布局

基础知识

1、定义表格容器

Grid 布局的开始都是开始于创建一个布局容器,可以通过在父元素声明display:grid;。只要我们这样声明了,这个父元素的所有直属子元素就变成了表格项目。在这点上和Flexbox是类似的。你会注意到css Gird 所有的表格样式都是定义到父元素上边的。

.parent {
  display: grid;
}

clipboard.png

现在所有直属子元素都是表格项目了。然后这并没有改变子元素的显示方式,因为我们只创建了一列。这里我们需要创建网格轨道来创建更多的列。一个网格轨道是相邻网格线之间的空间,实质就是行或者列。在上图中,每一个列之间的每个空间就是轨道。

2、添加行列

非常简单,我们可以使用grid-template-columnsgrid-template-rows属性来添加列和行

.parent {
  display: grid;
  grid-template-columns: 100px 100px 200px;
}

clipboard.png

现在我们有了3列,并分别给了他们100px 100px 和 200px的宽度。如果我们继续添加子元素,新增加的元素的宽素会继续按照100px 100px 和 200px的宽度顺序

clipboard.png

如果我们想要在表格子元素之间插入一些空格,我们应该怎么做呢?grid-gap就是做这个的。

.parent {
  display: grid;
  grid-template-columns: 100px 100px 200px;
  grid-gap: 10px;
}

clipboard.png

如果我们愿意的话,我们还可以使用grid-template-rows给每一行定义尺寸样式。在下面的例子中,第一行高度是50px,第二行高度是200px,如果添加第三行的话高度就是50p x

.parent {
  display: grid;
  grid-template-columns: 100px 100px 200px;
  grid-template-rows: 50px 200px 50px;
  grid-gap: 10px;
}

clipboard.png

那如何定义宽度可变的表格呢?

使用像素单位是没法做自适用的布局的

其实我们有fr这个单位,fr代表网格容器中可用空间的一小部分。所以我们切换pxfr

.parent {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-gap: 10px;
}

这里代表三个意思

  • 几列宽度是相等的(一个份数)

  • 列的宽度是可变的(屏幕宽度的一个份数)

  • 表格宽度根据容器宽度和元素之间的间距计算出来的

clipboard.png

注意:根据DRY原则,我们使用grid-template-columns: repeat(3, 1fr)定义多个相等宽度的列

如何定义宽度不等的列

我们可以仅仅改变份数的个数

.parent {
  display: grid;
  grid-template-columns: 1fr 2fr 1fr;
  grid-gap: 10px;
}

clipboard.png

我们同样可以使用混合单位。我们可能想要一列宽度是固定的,其他两列宽度相等。那可能的定义如下

.parent {
  display: grid;
  grid-template-columns: 1fr 300px 1fr;
  grid-gap: 10px;
}

向容器内插入尽可能多的网格元素

我们需要使用auto-fillauto-fit来完成这个。我们把上文的grid-template-columns元素属性改成下面这样子

.parent {
  display: grid;
  grid-template-columns: repeat(auto-fill, 200px);
  grid-gap: 10px;
}

auto-fill表示我们想要的轨道重复的次数。跟repeat(3, 200px)不同的是我们告诉网格容器尽可能多的插入200px的轨道(即便没有这么多轨道,也会插入隐形的不可见的轨道,或者按照有这么多轨道去布局)

clipboard.png

但是!我们好像又回到了刚才的问题了,我们如何实现可变的布局呢?每一列宽度都是固定的200px,当没有足够空间留给下一个元素的时候,下一个元素会自动切换到下一行。但是我们想要的是布满剩下的空间。

添加可变宽度的功能我们需要使用minmax。我们可以设置最小宽度200px最大宽度是一个份数的功能

.parent {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  grid-gap: 10px;
}

这代表着我们可以看到尽可能多的200px的轨道。但是, 如果有剩余的空间, 它将在它们之间平均分布。

clipboard.png

大部分时间,这些元素的宽度是大于200px,这根据浏览器的宽度而决定。但是宽度并不会小于200px并且是可变和自适用哒!!!

最后的障碍

最后一个问题就是当所有的元素都在第一行的时候

clipboard.png

使用auto-fill,Grid 创建尽可能多的子元素放置在容器内。所以当没有这么多元素的时候,会在后面留下一块空白。这在某一方面很实用,但是有时候我们并不想留下这么多空白,比如card布局。

仅用3行css实现响应式布局

我们可以使用auto-fit代替auto-fill解决上面提到的问题。auto-fit使用尽可能多的元素代替轨道,这就代表着会充满所有的空间。

auto-fill = 使用轨道充满空间
auto-fit = 使用元素充满空间

.parent {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  grid-gap: 10px;
}

How amazing!!!

翻译自 An introduction to CSS Grid


frontoldman
4.5k 声望1.3k 粉丝

前端开发者