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) 屬性。