css3 Grid Layout 表格布局是在css中强大的难以置信的布局模块。它是二维空间的,所以它可以处理行和列
它有些类似于Flexbox,但是又有本质的差别。Flexbox同样很强大,但是它主要是一维空间的。Flexbox可以处理列或者行,Grid可以同时处理两者。
综合运用它们,可以帮助我们在css中实现在之前无法想象的布局
基础知识
1、定义表格容器
Grid 布局的开始都是开始于创建一个布局容器,可以通过在父元素声明display:grid;
。只要我们这样声明了,这个父元素的所有直属子元素就变成了表格项目。在这点上和Flexbox是类似的。你会注意到css Gird 所有的表格样式都是定义到父元素上边的。
.parent {
display: grid;
}
现在所有直属子元素都是表格项目了。然后这并没有改变子元素的显示方式,因为我们只创建了一列。这里我们需要创建网格轨道来创建更多的列。一个网格轨道是相邻网格线之间的空间,实质就是行或者列。在上图中,每一个列之间的每个空间就是轨道。
2、添加行列
非常简单,我们可以使用grid-template-columns
和grid-template-rows
属性来添加列和行
.parent {
display: grid;
grid-template-columns: 100px 100px 200px;
}
现在我们有了3列,并分别给了他们100px 100px 和 200px的宽度。如果我们继续添加子元素,新增加的元素的宽素会继续按照100px 100px 和 200px的宽度顺序
如果我们想要在表格子元素之间插入一些空格,我们应该怎么做呢?grid-gap
就是做这个的。
.parent {
display: grid;
grid-template-columns: 100px 100px 200px;
grid-gap: 10px;
}
如果我们愿意的话,我们还可以使用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;
}
那如何定义宽度可变的表格呢?
使用像素单位是没法做自适用的布局的
其实我们有fr
这个单位,fr
代表网格容器中可用空间的一小部分。所以我们切换px
到fr
。
.parent {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 10px;
}
这里代表三个意思
几列宽度是相等的(一个份数)
列的宽度是可变的(屏幕宽度的一个份数)
表格宽度根据容器宽度和元素之间的间距计算出来的
注意:根据DRY原则,我们使用grid-template-columns: repeat(3, 1fr)
定义多个相等宽度的列
如何定义宽度不等的列
我们可以仅仅改变份数的个数
.parent {
display: grid;
grid-template-columns: 1fr 2fr 1fr;
grid-gap: 10px;
}
我们同样可以使用混合单位。我们可能想要一列宽度是固定的,其他两列宽度相等。那可能的定义如下
.parent {
display: grid;
grid-template-columns: 1fr 300px 1fr;
grid-gap: 10px;
}
向容器内插入尽可能多的网格元素
我们需要使用auto-fill
和auto-fit
来完成这个。我们把上文的grid-template-columns
元素属性改成下面这样子
.parent {
display: grid;
grid-template-columns: repeat(auto-fill, 200px);
grid-gap: 10px;
}
auto-fill
表示我们想要的轨道重复的次数。跟repeat(3, 200px)
不同的是我们告诉网格容器尽可能多的插入200px的轨道(即便没有这么多轨道,也会插入隐形的不可见的轨道,或者按照有这么多轨道去布局)
但是!我们好像又回到了刚才的问题了,我们如何实现可变的布局呢?每一列宽度都是固定的200px,当没有足够空间留给下一个元素的时候,下一个元素会自动切换到下一行。但是我们想要的是布满剩下的空间。
添加可变宽度的功能我们需要使用minmax
。我们可以设置最小宽度200px最大宽度是一个份数的功能
.parent {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-gap: 10px;
}
这代表着我们可以看到尽可能多的200px的轨道。但是, 如果有剩余的空间, 它将在它们之间平均分布。
大部分时间,这些元素的宽度是大于200px,这根据浏览器的宽度而决定。但是宽度并不会小于200px并且是可变和自适用哒!!!
最后的障碍
最后一个问题就是当所有的元素都在第一行的时候
使用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