CSS網格佈局(Grid)是一套二維的頁面佈局系統,它的出現將徹底顛覆頁面佈局的傳統方式。傳統的CSS頁面佈局 一直不夠理想。包括table佈局、浮動、定位及內聯塊等方式,從本質上都是Hack的方式,而且遺漏了一些重要的功能(好比:垂直居中)。Flexbox的出現部分解決了上述問題,但Flex佈局是爲了解決簡單的一維佈局,適用於頁面局部佈局。而Grid自然就是爲了解決複雜的二維佈局而出現的,適用頁面的總體佈局。在實際工做中,Grid和Flexbox不但不矛盾,並且還能很好的結合使用。作爲WEB程序員,咱們在頁面佈局問題上都付出過努力,也將不斷探索新的方案。而Grid是第一個專門爲佈局問題而生的CSS模塊,咱們有理由對Grid充滿期待。css
本文包括18個小節,62個實例,完整閱讀須要時間20分鐘以上。css3
爲了得到最佳的閱體驗,能夠訪問以下格式的教程:程序員
學習CSS網格網絡
將屬性 display
值設爲 grid
或 inline-grid
就建立了一個網格容器,全部容器直接子結點自動成爲網格項目。ide
grid {
display: grid;
}
複製代碼
網格項目按行排列,網格項目佔用整個容器的寬度。函數
演示程序佈局
grid {
display: inline-grid;
}
複製代碼
網格項目按行排列,網格項目寬度由自身寬度決定。學習
演示程序ui
屬性grid-template-rows
和grid-template-columns
用於顯示定義網格,分別用於定義行軌道和列軌道。spa
grid {
display: grid;
grid-template-rows: 50px 100px;
}
複製代碼
屬性grid-template-rows
用於定義行的尺寸,即軌道尺寸。軌道尺寸能夠是任何非負的長度值(px,%,em,等)
網格項目1的行高是50px,網格項目2的行高是100px。
由於只定義了兩個行高,網格項目3和4的行高取決於其自己的高度。
grid {
display: grid;
grid-template-columns: 90px 50px 120px;
}
複製代碼
相似於行的定義,屬性grid-template-columns
用於定義列的尺寸。
由於定義中只有三列,因此項目4,5,6排在新的一行; 並由於它們位於第1,2,3列的軌道上,因此其寬度等於定義中第1,2,3列軌道的寬度。
網格項目的第1列,第2列,第3列的寬度分別是 90px, 50px 和 120px 。
grid {
display: grid;
grid-template-columns: 1fr 1fr 2fr;
}
複製代碼
單位fr
用於表示軌道尺寸配額,表示按配額比例分配可用空間。
本例中,項目1佔 1/4 寬度,項目2佔 1/4 寬度,項目3佔 1/2 寬度。
grid {
display: grid;
grid-template-columns: 3rem 25% 1fr 2fr;
}
複製代碼
單位fr
和其它長度單位混合使用時,fr
的計算基於其它單位分配後的剩餘空間。
本例中,1fr = (容器寬度 - 3rem - 容器寬度的25%) / 3
函數minmax()
用於定義軌道最小/最大邊界值。
grid {
display: grid;
grid-template-rows: minmax(100px, auto);
grid-template-columns: minmax(auto, 50%) 1fr 3em;
}
複製代碼
函數minmax()
接收兩個參數:第一個參數表示最小軌道尺寸,第二個參數表示最大軌道尺寸。長度值能夠是auto,表示軌道尺寸能夠根據內容大小進行伸長或收縮。
本例中,第一行最小高度設置成100px,可是最大高度設置成auto
,表示行高能夠根據內容伸長超過100px。
本例中,第一列寬度的最大值設置成50%,表示其寬度不能超過整個容器寬度的50%。
函數repeat()
用來定義重複的網格軌道,尤爲適用於有多個相同項目的狀況下。
grid {
display: grid;
grid-template-rows: repeat(4, 100px);
grid-template-columns: repeat(3, 1fr);
}
複製代碼
函數repeat()
接收兩個參數:第一個參數表示重複的次數,第二個參數表示軌道尺寸。
grid {
display: grid;
grid-template-columns: 30px repeat(3, 1fr) 30px;
}
複製代碼
函數repeat()
能夠用在軌道定義列表當中。
本例中,第1列和第5列的寬度是30px。函數repeat()
建立了中間3列,每一列寬度都是1fr
。
屬性grid-column-gap
和 grid-row-gap
用於定義網格間隙。
網格間隙只建立在行列之間,項目與邊界之間無間隙。
grid {
display: grid;
grid-row-gap: 20px;
grid-column-gap: 5rem;
}
複製代碼
間隙尺寸能夠是任何非負的長度值(px,%,em等)。
grid {
display: grid;
grid-gap: 100px 1em;
}
複製代碼
屬性grid-gap
是grid-row-gap
和grid-column-gap
的簡寫形式。
第一個值表示行間隙,第二個值表示列間隙。
grid {
display: grid;
grid-gap: 2rem;
}
複製代碼
如只有一個值,則其即表示行間隙,也表示列間隙。
網格線本質上是用來表示網格軌道的開始和結束。
每一條網格線編號都以1開始,以1爲步長向前編號,其中包括行列兩組網格線。
.item1 {
grid-row-start: 2;
grid-row-end: 3;
grid-column-start: 2;
grid-column-end: 3;
}
複製代碼
這是一個3行2列的網格,即在行上有4條網格線,在列上有3條網格線。項目1利用網格線編號定位在第2行第2列的位置上。
本例中,項目只跨越一行一列,則grid-row-end
和grid-column-end
的定義能夠省略。
.item1 {
grid-row: 2;
grid-column: 3 / 4;
}
複製代碼
屬性grid-row
是 grid-row-start
和 grid-row-end
的簡寫形式。
屬性grid-column
是 grid-column-start
和 grid-column-end
的簡寫形式。
若是隻指定一個值,它表示 grid-row/column-start
。
若是兩個值都指定,第一個表示 grid-row/column-start
,第二個值表示grid-row/column-end
。並且你必須用斜槓(/)分隔這兩個值。
.item1 {
grid-area: 2 / 2 / 3 / 3;
}
複製代碼
屬性grid-area
是 grid-row-start
, grid-column-start
, grid-row-end
和 grid-column-end
的簡寫形式。
若是四個值都指定,則第一個表示 grid-row-start
, 第二個表示 grid-column-start
, 第三個表示 grid-row-end
,第四個表示 grid-column-end
。
網格項目默認都佔用一行和一列,但可使用前一節中定位項目的屬性來指定項目跨越多行或多列。
.item1 {
grid-column-start: 1;
grid-column-end: 4;
}
複製代碼
經過grid-column-start
和grid-column-end
屬性值的設置,使該網格項目跨越多列。
.item1 {
grid-row-start: 1;
grid-row-end: 4;
}
複製代碼
經過grid-row-start
和grid-row-end
屬性值的設置,使該網格項目跨越多行。
.item1 {
grid-row: 2 / 5;
grid-column: 2 / 4;
}
複製代碼
簡寫屬性 grid-row
和 grid-column
即能用來定位項目,也能用來使項目跨越多個行列。
.item1 {
grid-row: 2 / span 3;
grid-column: span 2;
}
複製代碼
關鍵字 span
用來指定跨越行或列的數量。
當利用屬性grid-template-rows
和 grid-template-columns
定義網格時,能夠同時定義網格線的名稱。網格線名稱能夠用於定位網格項目。
grid {
display: grid;
grid-template-rows: [row-1-start] 1fr [row-2-start] 1fr [row-2-end];
grid-template-columns: [col-1-start] 1fr [col-2-start] 1fr [col-3-start] 1fr [col-3-end];
}
複製代碼
用屬性grid-template-rows
和 grid-template-columns
定義網格,同時定義網格線名稱。
爲避免混淆,網格線名稱應避免使用規範中的關鍵字(span
等)。
定義網格線名稱的方法是要將其放在中括號內([name-of-line]
),並要和網格軌道相對應。
grid {
display: grid;
grid-template-rows: [row-start row-1-start] 1fr [row-1-end row-2-start] 1fr [row-2-end row-end];
grid-template-columns: [col-start] 1fr [col-2-start] 1fr [col-3-start] 1fr [col-end];
}
複製代碼
能夠給同一網格線定義多個名稱,方法就是在中括號內用空格將多個名稱分開。
每個網格線名均可以被引用,以用來定位網格項目。
利用命名的網格線,能夠很方便地進行項目定位。
.item1 {
grid-row-start: row-2-start;
grid-row-end: row-end;
grid-column-start: col-2-start;
grid-column-end: col-end;
}
複製代碼
引用網格線名稱不用加中括號。
.item1 {
grid-row: row-2-start / row-end;
grid-column: col-2-start / col-end;
}
複製代碼
簡寫屬性grid-row
和 grid-column
也能夠利用網格線名稱來定位項目。
函數repeat()
能夠定義同名網格線。這節省了給每條網格都命名的時間。
grid {
display: grid;
grid-template-rows: repeat(3, [row-start] 1fr [row-end]);
grid-template-columns: repeat(3, [col-start] 1fr [col-end]);
}
複製代碼
函數repeat()
能夠用來定義同名網格線。 這樣多個網格線擁有相同的名字。
同名網格線會被分配一個位置編號,作爲其惟一標識。
.item1 {
grid-row: row-start 2 / row-end 3;
grid-column: col-start / col-start 3;
}
複製代碼
用同名網格線來定位項目時,應注意在網格線名稱和編號之間有一個空格。
本例中,項目1的行定位開始於第2條名稱是row-start
的網格線,結束於第3條名稱是row-end
的網格線;列定位開始於第1條名稱是col-start
的網格線,結束於第3條名稱是col-start
的網格線。
如同網格線命名,能夠用屬性grid-template-areas
給網格區域命名。網格區域名稱能夠用來定位網格項目。
grid {
display: grid;
grid-template-areas: "header header"
"content sidebar"
"footer footer";
grid-template-rows: 150px 1fr 100px;
grid-template-columns: 1fr 200px;
}
複製代碼
一組區域名稱要放在單引號或雙引號內,每個名稱之間以空格分隔。
每一組名稱定義一行,每個名稱定義一列。
header {
grid-row-start: header;
grid-row-end: header;
grid-column-start: header;
grid-column-end: header;
}
複製代碼
網格區域名稱能夠用在屬性grid-row-start
, grid-row-end
, grid-column-start
, 和 grid-column-end
的值中,用來定位項目。
footer {
grid-row: footer;
grid-column: footer;
}
複製代碼
網格區域名稱也能夠用於簡寫屬性grid-row
和 grid-column
的值中。
aside {
grid-area: sidebar;
}
複製代碼
網格區域名稱也能夠用於簡寫屬性grid-area
的值中。
隱式網格用來在顯式網格以外定位項目。有時在顯示網格中沒有足夠的空間,或者是要在顯示網格以外定位項目就要用到隱式網格。這時能夠把這些項目放置在隱式網格中。
隱式網格能夠經過屬性 grid-auto-rows
, grid-auto-columns
, 和 grid-auto-flow
來定義。
grid {
display : grid;
grid-template-rows: 70px;
grid-template-columns: repeat(2, 1fr);
grid-auto-rows: 140px;
}
複製代碼
本例中,只定一個行軌道,所以項目 1 和 2 高 70px 。
第2行軌道有隱式網格自動建立併爲項目 3 和 4 分配了空間。 屬性grid-auto-rows
定義了隱式網格的行軌道尺寸,即項目3和4的高度是 140px 。
grid {
display : grid;
grid-auto-flow: row;
}
複製代碼
缺省的網格佈局方向是行的方向(row
)。
grid {
display : grid;
grid-auto-flow: column;
}
複製代碼
網格的佈局方向能夠定義爲列的方向(column)。
grid {
display : grid;
grid-template-columns: 30px 60px;
grid-auto-flow: column;
grid-auto-columns: 1fr;
}
複製代碼
本例中,咱們只定義了兩個列軌道的尺寸30px 和 60px。
隱式網格中自動建立其它列並給項目3,4,5分配空間;分配的空間尺寸是經過屬性 grid-auto-columns
定義的。
網格線名稱能夠任意指定,但分配以 -start
和 -end
結尾的名字有額外的益處,這樣隱式地建立了具名網格區域,該名稱能夠用於項目定位。
grid {
display : grid;
grid-template-rows: [outer-start] 1fr [inner-start] 1fr [inner-end] 1fr [outer-end];
grid-template-columns: [outer-start] 1fr [inner-start] 1fr [inner-end] 1fr [outer-end];
}
複製代碼
本例中,行和列都有名爲inner-start
和 inner-end
的網格線,它們隱式地給網格區域分派了名稱(inner
)。
item1 {
grid-area: inner;
}
複製代碼
這樣咱們就可以直接使用網格區域名來定位,而不須要再用網格線來定位項目了。
隱式命名網格線和隱式命名的網格區域的工做原理恰好相反。
grid {
display : grid;
grid-template-areas: "header header"
"content sidebar"
"footer footer";
grid-template-rows: 80px 1fr 40px;
grid-template-columns: 1fr 200px;
}
複製代碼
定義網格區域時隱式的命名了網格線的名稱。這些網格線的名稱是基於區域名加上-start
或 -end
後綴組成的。
item1 {
grid-row-start: header-start;
grid-row-end: content-start;
grid-column-start: footer-start;
grid-column-end: sidebar-end;
}
複製代碼
本例中,header是經過隱式網格線名稱進行定位的。
經過項目定位可使多個項目層疊在一塊兒,屬性z-index
能夠改變層疊項目的層次。
.item-1, .item-2 {
grid-row-start: 1;
grid-column-end: span 2;
}
.item-1 { grid-column-start: 1; z-index: 1; }
.item-2 { grid-column-start: 2 }
複製代碼
本例中,項目1 和 2 行定位開始於第1條行網格線,並跨越兩列。
兩個項目都是用網格線編號進行定位。項目1起始於第1條列網格線,項目2起始於第2條列網格線,這使得兩個項目在第一行中間列發生層疊。
缺省狀況下,項目2將層疊於項目1之上;然而,給項目1設置屬性z-index: 1
就使得項目1層疊於項目2之上。
.overlay {
grid-row-start: header-start;
grid-row-end: content-end;
grid-column-start: content-start;
grid-column-end: sidebar-start;
z-index: 1;
}
複製代碼
本例中,利用在 grid-template-areas
定義中的隱式網格線名稱,定位了一個網格項目(overlay
),並將層疊於上層。
CSS的 盒模型對齊模塊 補充了CSS網格的內容,網格項目能夠按行或列的軸線方向實現多種對齊方式。
屬性justify-items
和 justify-self
以行軸爲參照對齊項目,屬性align-items
和 align-self
以列軸爲參照對齊項目。
屬性justify-items
和 align-items
是網格容器的屬性,並支持以下這些值:
.grid {
grid-template-rows: 80px 80px;
grid-template-columns: 1fr 1fr;
grid-template-areas: "content content"
"content content";
}
.item { grid-area: content }
.grid {
justify-items: start
}
複製代碼
在行的軸線起點處對齊。
grid {
justify-items: center;
}
複製代碼
在行的軸線中點處對齊。
grid {
justify-items: end;
}
複製代碼
在行的軸線終點處對齊。
grid {
justify-items: stretch;
}
複製代碼
在行的軸線方向延伸並填滿整個區域。stretch
是缺省值。
grid {
align-items: start;
}
複製代碼
在列的軸線起點處對齊。
grid {
align-items: center;
}
複製代碼
在列的軸線中點處對齊。
grid {
align-items: end;
}
複製代碼
在列的軸線終點處對齊。
grid {
align-items: stretch;
}
複製代碼
在列的軸線方向延伸並填滿整個區域。
grid {
justify-items: center;
align-items: center;
}
複製代碼
項目定位於行軸和列軸線的中間位置。
項目能夠用屬性align-self 和 justify-self定義本身的對齊方式,並支持以下這些屬性值:
.item1 { justify-self: start }
.item2 { justify-self: center }
.item3 { justify-self: end }
複製代碼
屬性justify-self
在行的軸線方向定義對齊方式。
.item1 { align-self: start }
.item2 { align-self: center }
.item3 { align-self: end }
複製代碼
屬性align-self
在列的軸線方向定義對齊方式。
.item1 {
justify-self: center
align-self: center
}
複製代碼
項目1定位在行的軸線和列的軸線的中間位置。
在網格容器中,網格軌道延軸線方向有多種對齊方式。
屬性align-content
用於定義網格軌道延着行的軸線的對齊方式,而屬性justify-content
用於定義網格軌道沿着列的軸線的對齊方式。並分別支持以下屬性:
.grid {
width: 100%;
height: 300px;
grid-template-columns: repeat(4, 45px);
grid-template-rows: repeat(4, 45px);
grid-gap: 0.5em;
justify-content: start;
}
複製代碼
列的軌道在行的軸線起點處對齊。start
是缺省值。
.grid {
justify-content: end;
}
複製代碼
列的軌道在行的軸線終點處對齊。
.grid {
justify-content: center;
}
複製代碼
列的軌道在行的軸線中間處對齊。
.grid {
justify-content: space-around;
}
複製代碼
在每一列的兩側平均分配額外空間。
.grid {
justify-content: space-between;
}
複製代碼
在列與列之間平均分配額外的空間。
.grid {
justify-content: space-evenly;
}
複製代碼
在列與列之間及列與邊界之間平均分配額外空間。
.grid {
align-content: start;
}
複製代碼
行的軌道在列的軸線起點處對齊,屬性start
是缺省值。
.grid {
align-content: end;
}
複製代碼
行的軌道在列的軸線終點處對齊。
.grid {
align-content: center;
}
複製代碼
行的軌道在列的軸線中點處對齊。
.grid {
align-content: space-around;
}
複製代碼
每一行的兩側平均分配額外空間。
.grid {
align-content: space-between;
}
複製代碼
在行與行之間平均分配額外空間。
.grid {
align-content: space-evenly;
}
複製代碼
在行與行之間及行與邊界之間平均分配額外空間。
本教程相對全面地介紹了網格的相關內容,但這並非一個完整的技術文檔。想更全面的學習相關內容,推薦訪問 Mozilla開發者網絡 和 W3C 的網格文檔。
因爲能力有限,翻譯中不免錯誤較多,還請你們多多諒解!
十分感謝原文做者Jonathan Suh在本文排版設計,示例製做,文字編輯等方面卓越的工做。
爲了得到最佳的閱體驗,請訪問以下排版的教程: