CSS Grid 布局是 CSS 中最强大的布局系统。与 flexbox 的一维布局系统不同,CSS Grid 布局是一个二维布局系统,也就意味着它可以同时处理列和行。通过将 CSS 规则应用于 父元素 (成为 Grid Container 网格容器)和其 子元素(成为 Grid Items 网格项),你就可以轻松使用 Grid(网格) 布局。
简介
CSS Grid(网格) 布局(又称为 “Grid(网格)” ),是一个二维的基于网格的布局系统它的目标是完全改变我们基于网格的用户界面的布局方式。CSS 一直用来布局我们的网页,但一直以来都存在这样或那样的问题。一开始我们用表格(table),然后是浮动(float),再是定位(postion)和内嵌块(inline-block),但是所有这些方法本质上都是只是 hack 而已,并且遗漏了很多重要的功能(例如垂直居中)。Flexbox 的出现很大程度上改善了我们的布局方式,但它的目的是为了解决更简单的一维布局,而不是复杂的二维布局(实际上 Flexbox 和 Grid 能结合在一起工作,而且配合得非常好)。Grid(网格) 布局是第一个专门为解决布局问题而创建的 CSS 模块,我们终于不需要想尽办法hack 页面布局样式了。
有两个主要的事情启发我创建了本指南。第一个是 Rachel Andrew 出色的书籍 为CSS网格布局做好准备。这本书彻底,清晰的介绍 CSS Grid(网格) ,也是本指南的基础。我强烈建议你购买并阅读。另一个灵感来自 Flexbox 完整指南 ,这也是我学习 flexbox 经常前往的资源。这篇文章是帮助了很多人,显然是因为 Google “flexbox” 排名第一。你会发现它和我的文章有很多相似之处,为什么不跟从最好的呢?
本指南的目的是介绍存在于最新版本的规范中 Grid(网格) 概念。所以我不会覆盖过时的 IE 语法,而且随着规范的逐渐成熟,我会尽我最大的努力去更新这个指南。
基础知识和浏览器支持
首先,你必须使用 display: grid
将容器元素定义为一个 grid(网格) 布局,使用 grid-template-columns
和 grid-template-rows
设置 列 和 行 的尺寸大小,然后通过 grid-column
和 grid-row
将其子元素放入这个 grid(网格) 中。与 flexbox 类似,网格项(grid items)的源顺序无关紧要。你的 CSS 可以以任何顺序放置它们,这使得使用 媒体查询(media queries)重新排列网格变得非常容易。定义整个页面的布局,然后完全重新排列布局以适应不同的屏幕宽度,这些都只需要几行 CSS ,想象一下就让人兴奋。Grid(网格) 布局是有史以来最强大的CSS模块之一。
截至2017年3月,许多浏览器都提供了对 CSS Grid 的原生支持,而且无需加浏览器前缀:Chrome(包括 Android ),Firefox,Safari(包括iOS)和 Opera 。 另一方面,Internet Explorer 10和11支持它,但是是一个过时的语法实现。 Edge 已经宣布支持,但还没有到来。(愚人码头注:翻译这篇文章时,Edge 16 已经支持)。
这个浏览器支持数据来自 Caniuse ,你可以查看更多的细节。 数字表示支持以上功能的浏览器版本号。
桌面(Desktop) 浏览器
Chrome | Opera | Firefox | IE | Edge | Safari |
---|---|---|---|---|---|
57 | 44 | 52 | 11* | 16 | 10.1 |
手机(Mobile) / 平板(Tablet)浏览器
iOS Safari | Opera Mobile | Opera Mini | Android | Android Chrome | Android Firefox |
---|---|---|---|---|---|
10.3 | No | No | 62 | 62 | 57 |
除了微软之外,浏览器厂商似乎还没有对 Grid(网格) 搞自己的一套实现(比如加前缀),直到规范完全成熟。这是一件好事,因为这意味着我们不必担心学习多个语法。
在生产中使用 Grid 只是时间问题。 但现在是学习的时候了。
重要术语
在深入了解 Grid(网格) 的概念之前,理解术语是很重要的。由于这里涉及的术语在概念上都很相似,如果不先记住 Grid(网格) 规范定义的含义,很容易混淆它们。但是别担心,术语并不多。
网格容器(Grid Container)
应用 display: grid
的元素。这是所有网格项(Grid Items)的直接父级元素。在这个例子中,container
就是 网格容器(Grid Container)。
HTML 代码:
<div class="container">
<div class="item item-1"></div>
<div class="item item-2"></div>
<div class="item item-3"></div>
</div>
网格项(Grid Item)
网格容器(Grid Container)的子元素(例如直接子元素)。这里 item
元素就是网格项(Grid Item),但是 sub-item
不是。
HTML 代码:
<div class="container">
<div class="item"></div>
<div class="item">
<p class="sub-item"></p>
</div>
<div class="item"></div>
</div>
网格线(Grid Line)
构成网格结构的分界线。它们既可以是垂直的(“列网格线(column grid lines)”),也可以是水平的(“行网格线(row grid lines)”),并位于行或列的任一侧。例如,这里的黄线就是一条列网格线。
网格轨道(Grid Track)
两条相邻网格线之间的空间。你可以把它们想象成网格的列或行。下图是第二条和第三条 行网格线 之间的 网格轨道(Grid Track)。
网格单元格(Grid Cell)
两个相邻的行和两个相邻的列网格线之间的空间。这是 Grid(网格) 系统的一个“单元”。下图是第1至第2条 行网格线 和第2至第3条 列网格线 交汇构成的 网格单元格(Grid Cell)。
网格区域(Grid Area)
4条网格线包围的总空间。一个 网格区域(Grid Area) 可以由任意数量的 网格单元格(Grid Cell) 组成。下图是 行网格线1和3,以及列网格线1和3 之间的网格区域。
下篇继续介绍网格容器(Grid Container) 属性。