深刻探索 CSS Grid

做者:Hammad Ahmed

翻译:疯狂的技术宅css

原文:https://scotch.io/tutorials/d...前端

未经容许严禁转载程序员

简介

本教程将深刻探讨 CSS 网格布局,并探索几乎全部的属性和功能。读完以后,你将可以用这种出色的 CSS 附加功能去处理任何一种布局。面试

术语:Grid

Grid 是二维网格系统。它能够用来构建复杂的布局以及较小的界面。segmentfault

属性:display

只须要把一个元素的 display 属性设置为 grid,它就成了网格。浏览器

.grid-to-be {
    display: grid;
}

这样就使 .grid-to-be 成为 grid 容器,并使其子项成为 grid 项目服务器

术语:网格线

在定义明确的网格轨道时会建立网格线。你能够用它们去放置网格项微信

术语:网格轨道

网格线是两条网格线之间的空间。网格中的行和列是网格轨道。多线程

属性:grid-template-columns

可使用 grid-template-columns 属性来建立列。要定义列,应该按照你但愿它们在网格中出现的顺序,把grid -template-columns 属性设置为列大小。咱们来看一下:框架

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

这里定义了三个宽度为 100px 的列。全部网格项将会按顺序排列在这些列中。行高将等于该行中最高元素的高度,可是能够用 grid-template-rows 来进行更改。

请注意,在仅定义列而未定义行的状况下,元素将会填充列,而后在行中折返。这是因为 Grid 使用了网格线和网格线建立的隐式网格。

属性:grid-template-rows

grid-template-rows 用于定义网格中行的数量和大小。它的语法和 grid-template-columns 相似。

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

若是只有 grid-template-rows 而没有 grid-template-columns 属性会致使列宽等于该行中最宽元素的宽度。

属性:grid-template

gridgrid-template-rowsgrid-template-columnsgrid-template-areas 三个属性的简写。

使用方式以下:

.grid {
    grid-template:
        "header    header     header"  80px
        "nav       article    article" 600px
        / 100px 1fr;
}

你能够像平时那样去定义模板区域,将每行的宽度放在最右面,最后再把全部列的宽度放在正斜杠以后。像之前同样,你能够把全部内容放在一行。

数据类型:

fr 是为 CSS 网格布局建立的新单位。 fr 使你不须要计算百分比就能建立灵活的网格, 1fr 表示可用空间的一等份。可用空间被分为等份数字的总数个,因此 3fr 4fr 3fr 把空间划分为 3 + 4 + 3 = 10 个部分,分别为三行或列分配 三、4 和 3 个等份的可用空间。例如:

.grid {
    display: grid;
    grid-template-columns: 3fr 4fr 3fr;
}

若是将固定单位与弹性单位相混合,则每一个等份的可用空间是在减去固定空间后计算的。让咱们看另外一个例子:

.grid {
    display: grid;
    grid-template-columns: 3fr 200px 3fr;
}

单个等份的宽度是这样计算的:( .grid 的宽度 - 200px) / (3 + 3) 。若是存在间隔(gutter)的话,其空间一开始也会从 .grid 的宽度中减去。这是 fr 之间的区别,即百分比不包括你用 grid-gap 定义的 gutter。

这里的 3fr 200px 3fr 基本上等于 1fr 200px 1fr。

显式网格和隐式网格

显式网格是使用属性 grid-template-rowsgrid-template-columns 建立的网格。隐式网格由 Grid 建立的 网格线网格轨道 组成,用来保存带有 grid-template-* 属性的手动建立的网格以外的项目。

自动放置(Auto-placement)

当咱们建立这样的网格时:

.grid {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
}

即便咱们只定义了列,但做为 .grid 直接子项的单个单元格仍按行放置。这是由于 Grid 包含自动放置规则。

属性:grid-auto-columns

没有被 grid-template-columns 所定义的隐式建立的网格列轨道所建立的列的大小,能够用 grid-template-columns 属性定义,其默认值为 auto;你能够把它设置为本身所须要的值。

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

属性:grid-auto-rows

grid-auto-rows 的工做方式相似于 grid-template-columns

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

属性:grid-auto-flow

grid-auto-flow 属性控制 网格单元 如何流入网格,其默认值为 row

.grid {
    display: grid;
    grid-template-columns: 100px 100px 100px;
    grid-auto-flow: column;
}

上面网格中的“网格单元”将会被一一填充,直到没有剩余的项目为止。

基于行的放置

用行号将项目放置在网格中的操做被称为基于行的放置。

属性:grid-row-start

若是你但愿特定的网格项从特定的行开始,则能够这样:

.grid-item {
    grid-row-start: 3;
}

属性:grid-row-end

若是你但愿特定的网格项目在特定的行上结束,则能够这样:

.grid-item {
    grid-row-end: 6;
}

属性:grid-column-start

若是你但愿特定的网格项目从特定的列开始,能够这样:

.grid-item {
    grid-column-start: 3;
}

属性:grid-column-end

若是你但愿特定的网格项在特定的列上结束,能够这样:

.grid-item {
    grid-column-end: 6;
}

属性:grid-row 和 grid-column

能够用 grid-rowgrid-column 属性来手动放置和调整网格项目的大小。每一个属性都是其各自的 star 和 end 属性的简写:grid-row-startgrid-row-endgrid-column-startgrid-column-end

用正斜杠 “/ ”来分隔开始和结束值:

.grid-item {
    grid-column: 3 / 5;
    grid-row: 2 / 7;
}

属性:grid-area

你能够把 grid-area 用于对网格行和网格列的简写。它是这样的: / / /
.grid-item {
    grid-area: 2 / 3 / 7 / 5;
}

该代码的行为与上一个标题中的代码相同。

跨网格的元素

要使一个元素跨网格,可使用 grid-rowgrid-column 属性。设置起始行 1 和结束行 -1。此处 1 表示相关轴上最左边的网格线,-1 表示相关轴上最右边的网格线。在从右到左的书写脚本中,这是相反的,即 1 表示最右边的行,-1 表示最左边的行。

.grid-item-weird {
    grid-column: 1 / -1;
}

若是你但愿单个项目占据整个网格,能够对 grid-rowgrid-column 都这样作:

.grid-item-weird {
    grid-row: 1 / -1;
    grid-column: 1 / -1;
}

或者简单地:

.grid-item-weird {
    grid-area: 1 / 1 / -1 / -1;
}

关键字:span

当使用 grid-rowgrid-column 时,不用显式定义行号,而是能够用 span 关键字来声明该项应涵盖的行数或列数:

.grid-item {
    grid-column: 3 / span 2;
}

你也能够把项目固定在终点线上,并朝另外一个方向跨越。下面的代码实现了与上面相同的结果:

.grid-item {
    grid-column: span 2 / 5;
}

能够用相同的方式把 span 应用在行上。

术语:网格单元

网格单元格是四个相交的网格线之间的空间,就像表格中的单元格同样。

术语:网格区域

网格区域是占据网格上一个矩形区域的网格单元。它们是用命名的网格区域或基于行的放置建立的。

属性:grid-template-areas (& grid-area)

除了用诸如 spangrid-column之类的东西放置和调整单个网格项目外,还能够用所谓的“模板区域”。grid-template-area 容许你命名网格区域,以便网格项目能够进一步填充它们。

.grid {
    display: grid;
    grid-template-columns: 100px 1fr 100px;
    grid-template-rows: 100px 800px 100px;
    grid-template-areas:
        "header     header   header"
        "sidebar-1  content  sidebar-2"
        "footer     footer   footer"
}

这里的一对引号表明一行网格。你能够将全部内容放在一行中,而不用列对齐,可是我所作的只是为了使它看起来更加整洁。我首先定义了三列三行,而后为每一个单元命名。经过在第一行中重复执行三次 “header”,告诉 CSS 要作的是用名为 header 的网格项覆盖整个过程。其他的也同样。

如下是经过用 grid-template-areas 命名每一个网格项目,使其拥有为其定义的空间的方式:

.header {
    grid-area: header
}

.sidebar-1 {
    grid-area: sidebar-1
}

.content {
    grid-area: content
}

.sidebar-2 {
    grid-area: sidebar-2
}

.footer {
    grid-area: footer
}

没有什么比这更容易了,尤为是用于布置内容的 CSS 其余方法。

在前面你已经看到 grid-area 也用于基于行的定位。

若是想把单元格留空,则能够用点 . 来设置:

.grid {
    display: grid;
    grid-template-columns: 100px 1fr 100px;
    grid-template-rows: 100px 800px 100px;
    grid-template-areas:
        "header header header"
        "sidebar content sidebar"
        "footer footer ."
}

在这里,页脚以第二列结束。

属性:grid-template

gridgrid-template-rowsgrid-template-columnsgrid-template-areas 三个属性的简写。

使用方式以下所示:

.grid {
    grid-template:
        "header    header     header"  80px
        "nav       article    article" 200px
        / 100px auto;
}

能够像一般那样定义模板区域,把每行的宽度放在其最右面,而后将全部列的宽度放在正斜杠以后。像之前同样,你能够把全部得内容放在同一行。

函数:repeat()

repeat() 函数有助于使 网格轨道 列表变得不是那么多余,并为其添加了语义层。使用起来很是简单直观。咱们来看一下:

你也能够重复某种形式的轨道列表,以下所示:

.grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr 2fr); // this is the same as: 1fr 2fr 1fr 2fr 1fr 2fr
}
repeat() 没必要是值的惟一部分。你能够在其先后添加其余的值。例如: grid-template-columns:2fr repeat(5,1fr) 4fr;

属性:grid

这里的 gridgrid-template-rowsgrid-template-columnsgrid-template-areasgrid-auto-rowsgrid-auto-columnsgrid-auto-flow 六个属性的简写。

首先,你能够像这样使用 grid-template(上一个示例):

.grid {
    grid:
        "header    header     header"     80px
        "nav       article    article"    200px
        / 100px auto;
}

其次它不是你看上去的那样,gridcss 属性不同:

是的,你没有看错:一个名为 css 的属性,全部 CSS 属性的简写。我也是在某次思考中偶然知道了它。可是如今我不会教你怎么用,之后有可能会。

第三,你以某种方式使用 grid。你能够将 grid-template-rowsgrid-auto-columnsgrid-auto-rows 结合使用。语法很是简单:

.grid-item {
    grid: <grid-template-rows> / <grid-auto-columns>; 
    grid: <grid-auto-rows> / <grid-template-columns>; 
}

例如:

.grid-item-1 {
    grid: 50px 200px 200px/ auto-flow 60px;
}

.grid-item-2 {
    grid: auto-flow 50px / repeat(5, 1fr);
}
请注意,在该值以前应该先使用 auto-flow 关键字。

术语:Gutter

Gutter 是单独分隔 网格行网格列 的空间。 grid-column-gap, grid-row-gapgrid-gap 是用于定义 gutter 的属性。

属性:grid-row-gap

grid-row-gap 用于定义各个 网格行 之间的空间。它是这样的:

.grid {
    display: grid;
    grid-template-rows: 100px 100px 100px;
    grid-row-gap: 10px;
}

这会将 网格行 彼此隔开10个像素。

属性:grid-column-gap

grid-column-gap 用于定义各个 网格列 之间的空间。它是这样的:

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

这会将 网格列 彼此隔开 10 个像素。

属性:grid-gap

grid-gap 是将 grid-column-gapgrid-row-gap 结合在一块儿的简写属性。一个值定义了两个 gutter。例如:

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

属性:order

能够用 order 属性来控制网格单元的顺序。看下面的例子:

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

.grid .grid-cell:nth-child(5) {
    order: 1;
}

在代码中,第五个网格单元被放置在网格的最后,由于其余网格单元根本没有定义顺序。若是定义了顺序,则会遵循数字顺序。两个或多个 网格单元 能够有相同的顺序。具备相同顺序或彻底没有顺序的文件将会根据 HTML 文档的逻辑顺序进行放置。再看下面:

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

.grid .grid-cell {
    order: 1
}

.grid .grid-cell:nth-child(5) {
    order: 2;
}

上面的例子产生的结果与前面的例子相同。

函数:minmax()

maxmax() 函数是 CSS 网格布局的新增功能。此功能为咱们提供了指定 网格轨道 的最小和最大尺寸的方法。

看下面的例子:

.grid {
    display: grid;
    grid-template-columns: 1fr minmax(50px, 100px) 1fr;
}

使用上面的代码,在减少窗口宽度时,中间列将保持 100px 的宽度,直到第一列和最后一列减少到其内容的宽度为止。这对于制做响应式布局特别有用。

关键字:auto

若是父容器的尺寸是固定的(例如固定宽度),则 auto 关键字做为网格项目的宽度将会使该项目充满容器的整个宽度。在有多个项目的状况下,就像 fr 那样划分空间。可是若是将 autofr 一块儿使用,则 auto 表现为该项目内容的宽度,剩余的可用空间被划分为 fr

函数:fitcontent()

当你但愿宽度或高度表现得像 auto 同样,但又但愿受到最大宽度或高度约束时,能够用 fitcontent() 函数.

.grid-item {
    width: fitcontent(200px);
}

在这里,最小为适合内容,最大为 200px。

关键字:auto-fill

你能够用 auto-fill 来用最多的 网格轨道 填充相关的轴(行或列)而不会溢出。要实现这个目的,须要用到 repeat() 函数:

.grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, 50px);
}

但这会下降单个轨道的灵活性。经过与 minmax() 一块儿使用,能够同时具备自动填充功能和灵活性。

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

这样,你能够至少包含一列,而且在特定浏览器宽度中包含多个 50px 的列。

请注意,即便可能未用单元格填充, auto-fill 也会建立网格轨道。

auto-fit

auto-fit 的行为与 auto-fill 相同,不一样之处在于它会折叠全部空的重复轨道。空轨道是指没有放置网格项目或跨越网格项目的轨道。

dense

借助 dense 关键字,你能够将项目回填到 空网格单元 中,这些单元是由于你尝试作了一些的奇怪的事(例如spanning)而被建立的。在任何 span 内你均可以将 dense 关键字与 grid-auto-flow 配合使用,以下所示:

.grid {
    display: grid;
    grid-template-column: repeat(auto-fill, minmax(50px, 1fr));
    grid-auto-flow: dense;
}

你能够把它用在照片库之类的页面中,但在用于表单时要特别当心,由于这可能会打乱表单子元素的特定顺序。

浏览器支持

在撰写本文时,浏览器对 CSS 网格布局有很好的支持。根据 caniuse.com 的说法,除了 Internet Explorer 11部分支持 -ms 前缀和 Opera Mini 以外,全部主流浏览器均支持 CSS 网格布局。

总结

与之前的方法相比,CSS 网格使咱们可以以更高的控制力、便捷性和速度来进行布局。在本教程中,咱们学习了 Grid 的全部主要元素,包括建立轨道、定位和调整单元格的大小,以及使网格流畅和响应,以及使用诸如 auto-fillminmax() 之类的关键字。


本文首发微信公众号:前端先锋

欢迎扫描二维码关注公众号,天天都给你推送新鲜的前端技术文章

欢迎扫描二维码关注公众号,天天都给你推送新鲜的前端技术文章

欢迎继续阅读本专栏其它高赞文章:


相关文章
相关标签/搜索