CSS 柵格佈局 (亦稱 "Grid"),是一個基於柵格的二維佈局系統,旨在完全改變基於網格用戶界面的設計。CSS 一直以來並無把佈局作的足夠好。剛開始,咱們使用 tables,後來是 floats,positioning 和 inline-block,這些本質上是一些 hacks 並且許多重要功能還沒有解決(例如垂直居中)。Flexbox 能夠作到這些,可是它主要用來一些簡單的一維佈局,並不適合複雜的二維佈局(固然 Flexbox 與 Grid 能夠一併使用)。Grid 是第一個爲了解決佈局問題的 CSS 模塊,只要咱們作過網頁,就會遇到這些問題。css
有兩件事情在激勵着我創做這篇指南,首先是 Rachel Andrew 那本很是不錯的書 Get Ready for CSS Grid Layout.,清晰透徹地介紹了 Grid,它是本篇文章的基礎。我強烈建議你去購買而且閱讀它。另外一件事是 Chris Coyier 的文章 A Complete Guide to Flexbox,是關於 flexbox 的首選資源。它幫助了不少人,當你 Google "flexbox" 的時候,第一眼便可以看見它。或許你已經注意到個人文章與它有很大類似之處,但咱們有什麼理由不借鑑它呢?html
我會把 Grid 在最新版本規範上的概念呈現出來。所以,我將不會照顧過時的 IE 語法。當規範成熟時,我將盡量去按期更新。web
開始 Grid 是簡單的,你僅僅須要在容器(container)元素上定義一個柵格使用 display: grid
,並經過 grid-template-columns
與 grid-template-rows
設置行與列。經過設置 grid-column
和 grid-row
把子元素置於柵格中。與 flexbox
相似,柵格項目(items)的順序是可有可無的,你能夠經過 CSS 來控制順序。當使用媒體查詢時,改變它們的順序是極其簡單的。假設你設計好了網頁的佈局,但你須要適應不一樣的屏幕寬度,這僅僅須要幾行代碼,Grid 是最爲有效的模塊。算法
關於 Grid 一件很是重要的事情是你還不可以在生產環境中使用它。它目前僅僅是一個 W3C工做草案,並且不可以被任何瀏覽器默認支持。雖然IE10 與 IE11 可以支持它,但使用了過時語法舊的實現。爲了如今可以體驗 Grid,最好的方法是使用 Chrome, Opera 或者 Firefox,而且開啓特定的標誌。在 Chrome 中,導航到 chrome://flags 而且開啓 「experimental web platform features」。在 Opera 中一樣如此(opera://flags)。在 Firefox 中,開啓標誌 layout.css.grid.enabled(about:config)。chrome
這有一張瀏覽器支持表格,我將保持更新。瀏覽器
Chrome 29+ (Behind flag)
Safari Not supported
Firefox 40+ (Behind flag)
Opera 28+ (Behind flag)
IE 10+ (Old syntax)
Android Not supported
iOS Not supportedide
譯者注:如今有些最新瀏覽器的最新版本已經可以支持,能夠查看 caniuse 網站。佈局
你在生產環境中使用它僅僅是一個時間問題。可是,學習正在當下!學習
在深刻了解 Grid 概念以前,瞭解它的術語是極爲重要的。由於在此涉及到的術語概念類似,不易混淆。不過不用擔憂,他們並無不少。測試
設置 display: grid
的元素,它是全部柵格項目的直接父級元素。在這個例子中,container
是柵格的容器。
<div class="container"> <div class="item item-1"></div> <div class="item item-2"></div> <div class="item item-3"></div> </div>
柵格容器的直接子代。在這裏 item
是柵格項目,而 sub-item
不是柵格項目。
<div class="container"> <div class="item"></div> <div class="item"> <p class="sub-item"></p> </div> <div class="item"></div> </div>
組成柵格結構的分割線。它們位於行與列的兩側,有的是垂直的(列柵格線),有的是水平的(行柵格線)。如下黃色線是一個列柵格線。
相鄰柵格線的區域。你能夠認爲他們是柵格的一行或者一列。如下是第二與第三柵格線間的柵格軌跡。
相鄰行柵格線與相鄰列柵格線間的區域。它是柵格的獨立「單元」。如下柵格格子位於1,2行柵格線與2,3列柵格線間。
被四個柵格線圍繞的區域。一個柵格區域由任意數量的柵格格子組成。如下柵格區域位於1,3行柵格線與1,3列柵格線間。
屬於柵格容器的屬性:
屬於柵格項目的屬性:
定義該元素爲柵格項目,而且爲它的內容創建一個新的柵格格式上下文(grid formatting context)。
譯者注:還記得 BFC 與 IFC 嗎?
屬性值:
grid 生成塊狀柵格
inline-grid 生成行間柵格
subgrid 若是你的柵格容器自己是一個柵格項目的話(例如:嵌套柵格),你能夠根據它的父元素而不是它本身,指定行列大小。
.container{ display: grid | inline-grid | subgrid; }
注意:column
,float
,clear
與 vertical-align
在柵格容器上無效。
經過空格分隔的值定義柵格的行與列。值表明軌跡大小(track size),它們中間的間隙表明柵格線。
屬性值:
<track-size> 能夠是長度,百分比,或者柵格中的空白空間(使用 fr
)
<line-name> 任意名字,任君選擇
.container{ grid-template-columns: <track-size> ... | <line-name> <track-size> ...; grid-template-rows: <track-size> ... | <line-name> <track-size> ...; }
示例:
當你在軌跡值之間預留空格時,柵格線會被自動分配爲數值名字。
.container{ grid-template-columns: 40px 50px auto 50px 40px; grid-template-rows: 25% 100px auto; }
你也能夠爲柵格線設置名字,注意柵格線名字的括號語法:
.container{ grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end]; grid-template-rows: [row1-start] 25% [row1-end] 100px [third-line] auto [last-line]; }
注意一條線能夠有多個名字。例如,這裏第二條線有兩個名字:row1-end 和 row2-start。
.container{ grid-template-rows: [row1-start] 25% [row1-end row2-start] 25% [row2-end]; }
若是你定義的內容包含重複部分,你可使用 repeat()
標記去組織它。
.container{ grid-template-columns: repeat(3, 20px [col-start]) 5%; }
與如下代碼是等價的
.container{ grid-template-columns: 20px [col-start] 20px [col-start] 20px [col-start] 5%; }
fr
容許你設置軌跡大小爲柵格容器的一部分。例如,如下示例將設置每一個項目爲柵格容器的三分之一。
.container{ grid-template-columns: 1fr 1fr 1fr; }
空白空間將在固定項目 以後 被計算。在這個例子中,給 fr
分配的所有空餘時間不包括 50px。
.container{ grid-template-columns: 1fr 50px 1fr 1fr; }
經過指定柵格區域的名字來定義柵格模板,這樣柵格項目會經過 grid-area
屬性來指定區域。重複柵格區域的名字將會合並柵格格子,一個句點表示一個空的柵格格子。語法自己提供了一個可視化的柵格結構。
屬性值:
<grid-area-name> 在項目中使用 grid-area
屬性指定的柵格區域
. 句點表示空白柵格格子
none 不定義柵格區域
.container{ grid-template-areas: "<grid-area-name> | . | none | ..." "..." }
示例:
.item-a{ grid-area: header; } .item-b{ grid-area: main; } .item-c{ grid-area: sidebar; } .item-d{ grid-area: footer; } .container{ grid-template-columns: 50px 50px 50px 50px; grid-template-rows: auto; grid-template-areas: "header header header header" "main main . sidebar" "footer footer footer footer" }
這將建造一個三行四列的柵格。第一行所有由 header 區域組成,第二行由兩個 main 區域,一個空白格子與一個 sidebar 區域組成。最後一行所有由 footer 組成。
你聲明的每行都須要有相同數量的柵格格子。
你可使用任意數量無空格分割的相鄰句點去表示單個空白柵格格子。
譯者注:
grid-template-areas: "first . last"
與grid-template-areas: "first ...... last"
等價。
注意,這種語法僅僅能命名區域,而沒法命名柵格線。實際上,當你使用這種語法的時候,柵格區域兩端的柵格線已被自動命名。若是你的柵格區域叫 foo,柵格區域開始的行與列將被命名爲 foo-start,而結束的行與列將被命名爲 foo-end。這意味着一些柵格線會有不少名字,好比上述例子的最左邊的柵格線將會有三個名字:header-start, main-start 和 footer-start。
grid-template-columns
,grid-template-rows
和 grid-template-areas
的簡寫。
屬性值:
none 設置這三個屬性爲初始屬性
subgrid 設置 grid-template-rows
和 grid-template-columns
爲 subgrid
,grid-template-areas
爲初始值。
<grid-template-columns> / <grid-template-rows> 設置 grid-template-columns
與 grid-template-rows
爲各自指定的值。而 grid-template-areas
爲 none
。
.container{ grid-template: none | subgrid | <grid-template-columns> / <grid-template-rows>; }
另外,也有一個比較複雜可是方便的語法指定三個屬性,示例以下
.container{ grid-template: auto 50px auto / [row1-start] 25px "header header header" [row1-end] [row2-start] "footer footer footer" 25px [row2-end]; }
與如下代碼是等價的:
.container{ grid-template-columns: auto 50px auto; grid-template-rows: [row1-start] 25px [row1-end row2-start] 25px [row2-end]; grid-template-areas: "header header header" "footer footer footer"; }
由於 grid-template
沒法 隱式 重置屬性(grid-auto-columns
,grid-auto-rows
與 grid-auto-flow
)。或許你想作更多的事,那麼推薦你使用 grid
屬性去替代 grid-template
。
指定柵格線的大小,你能夠理解它爲設置行/列間隙。
屬性值:
<line-size> 長度值
.container{ grid-column-gap: <line-size>; grid-row-gap: <line-size>; }
示例:
.container{ grid-template-columns: 100px 50px 100px; grid-template-rows: 80px auto 80px; grid-column-gap: 10px; grid-row-gap: 15px; }
柵格間隙僅僅在行/列 之間,不包括最外部的邊。
grid-column-gap
與 grid-row-gap
的簡寫。
屬性值:
<grid-row-gap> <grid-column-gap> 長度值
.container{ grid-gap: <grid-row-gap> <grid-column-gap>; }
示例:
.container{ grid-template-columns: 100px 50px 100px; grid-template-rows: 80px auto 80px; grid-gap: 10px 15px; }
若是沒有設置 grid-row-gap
,它將於 grid-column-gap
保持一致。
使柵格項目中的內容與 列 軸對齊(相應地,align-items
與 行 軸對齊)。這個屬性值應用在容器中的全部項目上。
屬性值:
start 使內容與柵格區域左側對齊
end 使內容與柵格區域右側對齊
center 使內容在柵格區域中居中
stretch 使內容充滿整個柵格區域的寬(默認屬性)
.container{ justify-items: start | end | center | stretch; }
示例
.container{ justify-items: start; }
.container{ justify-items: end; }
.container{ justify-items: center; }
.container{ justify-items: stretch; }
這個行爲也能夠經過 justify-self
屬性設置在獨立的柵格項目上。
使柵格項目中的內容與 行 軸對齊(相應地,justify-items
與 列 軸對齊)。這個屬性值應用在容器中的全部項目上。
屬性值:
start 使內容與柵格區域頂部對齊
end 使內容與柵格區域底部對齊
center 使內容在柵格區域中居中
stretch 使內容充滿整個柵格區域的高(默認屬性)
.container{ align-items: start | end | center | stretch; }
示例:
.container{ align-items: start; }
.container{ align-items: end; }
.container{ align-items: center; }
.container{ align-items: stretch; }
這個行爲也能夠經過 align-self
屬性設置在獨立的柵格項目上。
有時候,柵格的總大小小於柵格容器的大小,好比你使用 px
給全部的柵格項目設置了固定大小。本例中,你能夠設置柵格容器中柵格的對齊。這個屬性會使柵格與 列 軸對齊(相應地,align-content
會使柵格與 行 軸對齊)。
屬性值:
start 與柵格容器的左側對齊
end 與柵格容器的右側對齊
center 在柵格容器中居中
stretch 調整柵格項目的大小,使柵格充滿整個柵格容器。
space-around 每兩個項目之間留有相同的空白,在最左端與最右端爲一半大小的空白。
space-between 每兩個項目之間留有相同的空白,在最左端與最右端不留空白。
space-evenly 每兩個項目之間留有相同的空白,包括兩端。
.container { align-content: start | end | center | stretch | space-around | space-between | space-evenly; }
示例:
.container{ justify-content: start; }
.container{ justify-content: end; }
.container{ justify-content: center; }
.container{ justify-content: stretch; }
.container{ justify-content: space-around; }
.container{ justify-content: space-between; }
.container{ justify-content: space-evenly; }
有時候,柵格的總大小小於柵格容器的大小,好比你使用 px
給全部的柵格項目設置了固定大小。本例中,你能夠設置柵格容器中柵格的對齊。這個屬性會使柵格與 行 軸對齊(相應地,align-content
會使柵格與 列 軸對齊)。
屬性值:
start 與柵格容器的頂部對齊
end 與柵格容器的底部對齊
center 在柵格容器中居中
stretch 調整柵格項目的大小,使柵格充滿整個柵格容器。
space-around 每兩個項目之間留有相同的空白,在最左端與最右端爲一半大小的空白。
space-between 每兩個項目之間留有相同的空白,在最左端與最右端不留空白。
space-evenly 每兩個項目之間留有相同的空白,包括兩端。
.container{ align-content: start | end | center | stretch | space-around | space-between | space-evenly; }
示例:
.container{ align-content: start; }
.container{ align-content: end; }
.container{ align-content: center; }
.container{ align-content: stretch; }
.container{ align-content: space-around; }
.container{ align-content: space-between; }
.container{ align-content: space-evenly; }
指定自動生成的柵格軌跡的大小(亦稱隱式柵格軌跡)。當你顯式定位行與列的時候(經過 grid-template-rows
/ grid-template-columns
),隱式柵格軌跡會在定義的柵格外被建立。
屬性值:
<track-size> 能夠是長度,百分比或者 fr
.container{ grid-auto-columns: <track-size> ...; grid-auto-rows: <track-size> ...; }
舉例瞭解隱式柵格軌跡是如何被建立的,考慮如下示例:
.container{ grid-template-columns: 60px 60px; grid-template-rows: 90px 90px }
本示例建造了 2 * 2 的柵格。
你使用 [grid-column
](#prop-grid-column) 與 grid-row
去定位你的項目以下:
.item-a{ grid-column: 1 / 2; grid-row: 2 / 3; } .item-b{ grid-column: 5 / 6; grid-row: 2 / 3; }
咱們告知 .item-b 在 5-6 列間,但咱們從未定義第五列或者第六列。由於咱們引用的柵格線不存在,寬度爲0的隱式柵格軌跡將會建立去填充空白。咱們可使用 grid-auto-columns
和 grid-auto-rows
去指定這些軌跡的寬。
譯者注:經譯者測試,並不是以寬度爲0的 implicit track 去填充。w3c auto-tracks 上代表
grid-auto-columns
的默認值爲auto
,則超過的列將會平分空白空間。
.container{ grid-auto-columns: 60px; }
若是你的柵格項目沒有顯式地在柵格中設置位置,自動放置算法便會生效。這個屬性控制自動放置算法的的運做。
屬性值:
row 自動放置算法將按行依次排列,按需添加新行。
column 自動放置算法將按列依次排列,按需添加新列。
dense 若是較小的項目出現靠後時,自動防止算法將盡量早地填充柵格的空白格子
.container{ grid-auto-flow: row | column | row dense | column dense }
注意 dense 可能使你的項目次序顛倒。
示例:
考慮如下 html:
<section class="container"> <div class="item-a">item-a</div> <div class="item-b">item-b</div> <div class="item-c">item-c</div> <div class="item-d">item-d</div> <div class="item-e">item-e</div> </section>
你定義了一個兩行五列的柵格,並設置它的 grid-auto-flow
屬性爲 row
(默認屬性即是 row
)。
.container{ display: grid; grid-template-columns: 60px 60px 60px 60px 60px; grid-template-rows: 30px 30px; grid-auto-flow: row; }
當咱們把項目放置在柵格中的時候,明確指定如下兩個項目的位置
.item-a{ grid-column: 1; grid-row: 1 / 3; } .item-e{ grid-column: 5; grid-row: 1 / 3; }
由於咱們設置了 grid-auto-flow
屬性爲 row
,呈如今咱們眼前的柵格即是以下這個樣子。注意,這三個項目(item-b,item-c 與 item-d)並無特地指定位置。
若是設置 grid-auto-flow
的屬性爲 column
,item-b,item-c 與 item-d** 將按列以此排序。
.container{ display: grid; grid-template-columns: 60px 60px 60px 60px 60px; grid-template-rows: 30px 30px; grid-auto-flow: column; }
如下屬性的縮寫:grid-template-rows
, grid-template-columns
, grid-template-areas
,grid-auto-rows
,grid-auto-columns
,與 [
grid-auto-flow](#prop-grid-auto-flow)
。它也能夠設置 grid-column-gap
和 grid-row-gap
爲默認值,即便並無在 grid
中明確設置。
屬性值:
none 設置全部子屬性的值爲初始值。
<grid-template-rows> / <grid-template-columns> 僅僅設置這兩個屬性值,其它子屬性值爲初始值。
<grid-auto-flow> [<grid-auto-rows> [ / <grid-auto-columns>] ] 若是 grid-auto-columns
屬性值確實,則採用 grid-auto-rows
的值。若是屬性值均缺失,則採用默認值。
.container{ grid: none | <grid-template-rows> / <grid-template-columns> | <grid-auto-flow> [<grid-auto-rows> [/ <grid-auto-columns>]]; }
如下兩種寫法是等價的:
.container{ grid: 200px auto / 1fr auto 1fr; }
.container{ grid-template-rows: 200px auto; grid-template-columns: 1fr auto 1fr; grid-template-areas: none; }
如下兩種寫法也是等價的:
.container{ grid: column 1fr / auto; }
.container{ grid-auto-flow: column; grid-auto-rows: 1fr; grid-auto-columns: auto; }
另外你能夠設置更爲複雜但至關方便的語法一次性設置全部屬性。你能夠指定grid-template-areas
, grid-auto-rows
與 grid-auto-columns
,其餘子屬性將被設爲默認值。你須要指定柵格線與軌跡大小,這很容易用一個例子表示:
.container{ grid: [row1-start] "header header header" 1fr [row1-end] [row2-start] "footer footer footer" 25px [row2-end] / auto 50px auto; }
與如下寫法是等價的:
.container{ grid-template-areas: "header header header" "footer footer footer"; grid-template-rows: [row1-start] 1fr [row1-end row2-start] 25px [row2-end]; grid-template-columns: auto 50px auto; }
經過指定柵格線來肯定柵格項目的位置。grid-column-start
/ grid-row-start
表明項目開始的線,grid-column-end
/grid-row-end
表明項目結束的線。
屬性值:
<Line> 能夠是一個表示柵格線名字或數字。
span <number> 項目將橫跨指定數量柵格軌跡
span <name> 項目將橫跨至指定名字的柵格線
auto 自動放置,自動跨越軌跡或者默認跨越軌跡
.item{ grid-column-start: <number> | <name> | span <number> | span <name> | auto grid-column-end: <number> | <name> | span <number> | span <name> | auto grid-row-start: <number> | <name> | span <number> | span <name> | auto grid-row-end: <number> | <name> | span <number> | span <name> | auto }
示例:
.item-a{ grid-column-start: 2; grid-column-end: five; grid-row-start: row1-start grid-row-end: 3 }
.item-b{ grid-column-start: 1; grid-column-end: span col4-start; grid-row-start: 2 grid-row-end: span 2 }
若是沒有指定 grid-column-end/grid-row-end,項目默認橫跨一個軌跡。
項目可能會互相重疊,你可使用 z-index
控制它們的層疊順序(stacking order)。
各自表示grid-column-start
+ grid-column-end
與 grid-row-start
+ grid-row-end
的縮寫。
屬性值:
<start-line> / <end-line> 接收 grid-column-start 一樣的屬性值,包括 span
.item{ grid-column: <start-line> / <end-line> | <start-line> / span <value>; grid-row: <start-line> / <end-line> | <start-line> / span <value>; }
Example:
.item-c{ grid-column: 3 / span 2; grid-row: third-line / 4; }
若是沒有指定 end line,項目將默認跨越一個軌跡。
當建立柵格容器使用 grid-template-areas
屬性時,能夠經過制定區域名字肯定柵格項目的位置。一樣,它也能夠做爲如下屬性的縮寫:grid-row-start
+ grid-column-start
+ grid-row-end
+ grid-column-end
。
屬性值:
<name>
<row-start> / <column-start> / <row-end> / <column-end>
.item{ grid-area: <name> | <row-start> / <column-start> / <row-end> / <column-end>; }
示例:
你能夠給項目設置名字:
.item-d{ grid-area: header }
也能夠做爲grid-row-start
+ grid-column-start
+ grid-row-end
+ grid-column-end
的縮寫:
.item-d{ grid-area: 1 / col4-start / last-line / 6 }
使柵格項目中的內容與 列 軸對齊(相應地,align-self
與 行 軸對齊)。本屬性值適用於單個項目的內容。
屬性值:
start 使內容與柵格區域左側對齊
end 使內容與柵格區域右側對齊
center 使內容在柵格區域中居中
stretch 使內容充滿整個柵格區域的寬(默認屬性)
.item{ justify-self: start | end | center | stretch; }
示例:
.item-a{ justify-self: start; }
.item-a{ justify-self: end; }
.item-a{ justify-self: center; }
.item-a{ justify-self: stretch; }
爲了對柵格項目中的全部項目設置對齊,能夠是指柵格容器的 justify-items
屬性。
使柵格項目中的內容與 行 軸對齊(相應地,justify-self
與列軸對齊)。本屬性值適用於單個項目的內容。
屬性值:
start 使內容與柵格區域頂部對齊
end 使內容與柵格區域底部對齊
center 使內容在柵格區域中居中
stretch 使內容充滿整個柵格區域的高(默認屬性)
.item{ align-self: start | end | center | stretch; }
示例:
.item-a{ align-self: start; }
.item-a{ align-self: end; }
.item-a{ align-self: center; }
.item-a{ align-self: stretch; }
爲了對柵格項目中的全部項目設置對齊,能夠設置柵格容器的 align-items
屬性。