Grid
佈局即網格佈局,是一種新的 CSS
佈局模型,比較擅長將一個頁面劃分爲幾個主要區域,以及定義這些區域的大小、位置、層次等關係。號稱是最強大的的 CSS
佈局方案,是目前惟一一種 CSS
二維佈局。利用 Grid
佈局,咱們能夠輕鬆實現相似下圖佈局,演示地址css
講到佈局,咱們就會想到 flex
佈局,甚至有人認爲居然有 flex
佈局了,彷佛沒有必要去了解 Grid
佈局。但 flex
佈局和 Grid
佈局有實質的區別,那就是 flex
佈局是一維佈局,Grid
佈局是二維佈局。flex
佈局一次只能處理一個維度上的元素佈局,一行或者一列。Grid
佈局是將容器劃分紅了「行」和「列」,產生了一個個的網格,咱們能夠將網格元素放在與這些行和列相關的位置上,從而達到咱們佈局的目的。html
Grid
佈局遠比 flex
佈局強大!前端
flex佈局示例:算法
Grid 佈局示例:瀏覽器
咱們使用 Grid 實現一個小例子,演示 Grid 的一些基礎概念,演示地址bash
<div class="wrapper">
<div class="one item">One</div>
<div class="two item">Two</div>
<div class="three item">Three</div>
<div class="four item">Four</div>
<div class="five item">Five</div>
<div class="six item">Six</div>
</div>
複製代碼
.wrapper {
margin: 60px;
/* 聲明一個容器 */
display: grid;
/* 聲明列的寬度 */
grid-template-columns: repeat(3, 200px);
/* 聲明行間距和列間距 */
grid-gap: 20px;
/* 聲明行的高度 */
grid-template-rows: 100px 200px;
}
.one {
background: #19CAAD;
}
.two {
background: #8CC7B5;
}
.three {
background: #D1BA74;
}
.four {
background: #BEE7E9;
}
.five {
background: #E6CEAC;
}
.six {
background: #ECAD9E;
}
.item {
text-align: center;
font-size: 200%;
color: #fff;
}
複製代碼
容器和項目:咱們經過在元素上聲明 display:grid
或 display:inline-grid
來建立一個網格容器。一旦咱們這樣作,這個元素的全部直系子元素將成爲網格項目。好比上面 .wrapper
所在的元素爲一個網格容器,其直系子元素將成爲網格項目。app
網格軌道:grid-template-columns
和 grid-template-rows
屬性來定義網格中的行和列。容器內部的水平區域稱爲行,垂直區域稱爲列。上圖中 One
、Two
、Three
組成了一行,One
、Four
則是一列ide
網格單元:一個網格單元是在一個網格元素中最小的單位, 從概念上來說其實它和表格的一個單元格很像。上圖中 One
、Two
、Three
、Four
...都是一個個的網格單元函數
網格線:劃分網格的線,稱爲"網格線"。應該注意的是,當咱們定義網格時,咱們定義的是網格軌道,而不是網格線。Grid 會爲咱們建立編號的網格線來讓咱們來定位每個網格元素。m 列有 m + 1 根垂直的網格線,n 行有 n + 1 跟水平網格線。好比上圖示例中就有 4 根垂直網格線。通常而言,是從左到右,從上到下,1,2,3 進行編號排序。固然也能夠從右到左,從下到上,按照 -1,-2,-3...順序進行編號排序佈局
Grid
佈局相關的屬性以及值衆多,須要記憶的很多,建議能夠跟 demo
一塊兒結合起來,邊敲代碼邊理解,再利用一些空閒時間記憶一下。筆者會在介紹每一個屬性的時候,作個小 demo
演示,建議你們能夠本身修改看看效果加深記憶
Grid
佈局屬性能夠分爲兩大類,一類是容器屬性,一類是項目屬性。咱們先來看容器屬性
咱們經過在元素上聲明 display:grid
或 display:inline-grid
來建立一個網格容器。聲明 display:grid
則該容器是一個塊級元素,設置成 display: inline-grid
則容器元素爲行內元素
.wrapper {
display: grid;
}
複製代碼
.wrapper-1 {
display: inline-grid;
}
複製代碼
grid-template-columns 和 grid-template-rows 屬性演示地址
grid-template-columns
屬性設置列寬,grid-template-rows
屬性設置行高,這兩個屬性在 Grid
佈局中尤其重要,它們的值是有多種多樣的,並且它們的設置是比較類似的,下面針對 grid-template-columns
屬性進行講解
固定的列寬和行高
.wrapper {
display: grid;
/* 聲明瞭三列,寬度分別爲 200px 100px 200px */
grid-template-columns: 200px 100px 200px;
grid-gap: 5px;
/* 聲明瞭兩行,行高分別爲 50px 50px */
grid-template-rows: 50px 50px;
}
複製代碼
以上表示固定列寬爲 200px 100px 200px,行高爲 50px 50px
repeat() 函數:能夠簡化重複的值。該函數接受兩個參數,第一個參數是重複的次數,第二個參數是所要重複的值。好比上面行高都是同樣的,咱們能夠這麼去實現,實際效果是如出一轍的
.wrapper-1 {
display: grid;
grid-template-columns: 200px 100px 200px;
grid-gap: 5px;
/* 2行,並且行高都爲 50px */
grid-template-rows: repeat(2, 50px);
}
複製代碼
auto-fill 關鍵字:表示自動填充,讓一行(或者一列)中儘量的容納更多的單元格。grid-template-columns: repeat(auto-fill, 200px)
表示列寬是 200 px,但列的數量是不固定的,只要瀏覽器可以容納得下,就能夠放置元素,代碼以及效果以下圖所示:
.wrapper-2 {
display: grid;
grid-template-columns: repeat(auto-fill, 200px);
grid-gap: 5px;
grid-auto-rows: 50px;
}
複製代碼
fr 關鍵字:Grid
佈局還引入了一個另外的長度單位來幫助咱們建立靈活的網格軌道。fr
單位表明網格容器中可用空間的一等份。grid-template-columns: 200px 1fr 2fr
表示第一個列寬設置爲 200px,後面剩餘的寬度分爲兩部分,寬度分別爲剩餘寬度的 1/3 和 2/3。代碼以及效果以下圖所示:
.wrapper-3 {
display: grid;
grid-template-columns: 200px 1fr 2fr;
grid-gap: 5px;
grid-auto-rows: 50px;
}
複製代碼
minmax() 函數:咱們有時候想給網格元素一個最小和最大的尺寸,minmax()
函數產生一個長度範圍,表示長度就在這個範圍之中均可以應用到網格項目中。它接受兩個參數,分別爲最小值和最大值。grid-template-columns: 1fr 1fr minmax(300px, 2fr)
的意思是,第三個列寬最少也是要 300px,可是最大不能大於第一第二列寬的兩倍。代碼以及效果以下:
.wrapper-4 {
display: grid;
grid-template-columns: 1fr 1fr minmax(300px, 2fr);
grid-gap: 5px;
grid-auto-rows: 50px;
}
複製代碼
auto 關鍵字:由瀏覽器決定長度。經過 auto
關鍵字,咱們能夠輕易實現三列或者兩列布局。grid-template-columns: 100px auto 100px
表示第一第三列爲 100px,中間由瀏覽器決定長度,代碼以及效果以下:
.wrapper-5 {
display: grid;
grid-template-columns: 100px auto 100px;
grid-gap: 5px;
grid-auto-rows: 50px;
}
複製代碼
grid-row-gap 屬性、grid-column-gap 屬性以及 grid-gap 屬性演示地址
grid-row-gap
屬性、grid-column-gap
屬性分別設置行間距和列間距。grid-gap
屬性是二者的簡寫形式。
grid-row-gap: 10px
表示行間距是 10px,grid-column-gap: 20px
表示列間距是 20px。grid-gap: 10px 20px
實現的效果是同樣的
.wrapper {
display: grid;
grid-template-columns: 200px 100px 100px;
grid-gap: 10px 20px;
grid-auto-rows: 50px;
}
複製代碼
.wrapper-1 {
display: grid;
grid-template-columns: 200px 100px 100px;
grid-auto-rows: 50px;
grid-row-gap: 10px;
grid-column-gap: 20px;
}
複製代碼
以上兩種寫法效果是同樣的。
grid-area 以及 grid-template-areas演示地址
grid-template-areas
屬性用於定義區域,一個區域由一個或者多個單元格組成
通常這個屬性跟網格元素的 grid-area
一塊兒使用,咱們在這裏一塊兒介紹。 grid-area
屬性指定項目放在哪個區域
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: 120px 120px 120px;
grid-template-areas:
". header header"
"sidebar content content";
background-color: #fff;
color: #444;
}
複製代碼
上面代碼表示劃分出 6 個單元格,其中值得注意的是 .
符號表明空的單元格,也就是沒有用到該單元格。
.sidebar {
grid-area: sidebar;
}
.content {
grid-area: content;
}
.header {
grid-area: header;
}
複製代碼
以上代碼表示將類 .sidebar
.content
.header
所在的元素放在上面 grid-template-areas
中定義的 sidebar
content
header
區域中
grid-auto-flow
屬性控制着自動佈局算法怎樣運做,精確指定在網格中被自動佈局的元素怎樣排列。默認的放置順序是"先行後列",即先填滿第一行,再開始放入第二行,即下圖英文數字的順序 one
,two
,three
...。這個順序由 grid-auto-flow
屬性決定,默認值是 row
。
.wrapper {
display: grid;
grid-template-columns: 100px 200px 100px;
grid-auto-flow: row;
grid-gap: 5px;
grid-auto-rows: 50px;
}
複製代碼
細心的同窗可能發現了一個問題,就是第五個項目和第六個項目之間有個空白(以下圖所示),這個是因爲第六塊的長度大於了空白處的長度,被擠到了下一行致使的。在實際應用中,咱們可能想讓下面長度合適的填滿這個空白,這個時候能夠設置 grid-auto-flow: row dense
,表示儘量填滿表格。代碼以及效果以下所示:
.wrapper-2 {
display: grid;
grid-template-columns: 100px 200px 100px;
grid-auto-flow: row dense;
grid-gap: 5px;
grid-auto-rows: 50px;
}
複製代碼
能夠設置 grid-auto-flow: column
,表示先列後行,代碼以及效果以下圖所示:
.wrapper-1 {
display: grid;
grid-auto-columns: 100px;
grid-auto-flow: column;
grid-gap: 5px;
grid-template-rows: 50px 50px;
}
複製代碼
justify-items 屬性、align-items 屬性演示地址
justify-items
屬性設置單元格內容的水平位置(左中右),align-items
屬性設置單元格的垂直位置(上中下)
下面以 justify-items 屬性爲例進行講解,align-items 屬性同理,只是方向爲垂直方向。它們都有以下屬性:
.container {
justify-items: start | end | center | stretch;
align-items: start | end | center | stretch;
}
複製代碼
其代碼實現以及效果以下:
.wrapper, .wrapper-1, .wrapper-2, .wrapper-3 {
display: grid;
grid-template-columns: 100px 200px 100px;
grid-gap: 5px;
grid-auto-rows: 50px;
justify-items: start;
}
.wrapper-1 {
justify-items: end;
}
.wrapper-2 {
justify-items: center;
}
.wrapper-3 {
justify-items: stretch;
}
複製代碼
justify-content 屬性、align-content 屬性演示地址
justify-content
屬性是整個內容區域在容器裏面的水平位置(左中右),align-content
屬性是整個內容區域的垂直位置(上中下)。它們都有以下的屬性值。
.container {
justify-content: start | end | center | stretch | space-around | space-between | space-evenly;
align-content: start | end | center | stretch | space-around | space-between | space-evenly;
}
複製代碼
下面以 justify-content
屬性爲例進行講解,align-content
屬性同理,只是方向爲垂直方向
.wrapper, .wrapper-1, .wrapper-2, .wrapper-3, .wrapper-4, .wrapper-5, .wrapper-6 {
display: grid;
grid-template-columns: 100px 200px 100px;
grid-gap: 5px;
grid-auto-rows: 50px;
justify-content: start;
}
.wrapper-1 {
justify-content: end;
}
.wrapper-2 {
justify-content: center;
}
複製代碼
.wrapper-3 {
justify-content: space-around;
}
.wrapper-4 {
justify-content: space-between;
}
.wrapper-5 {
justify-content: space-evenly;
}
.wrapper-6 {
justify-content: stretch;
}
複製代碼
grid-auto-columns 屬性和 grid-auto-rows 屬性演示地址
在講 grid-auto-columns
屬性和 grid-auto-rows
屬性以前,先來看看隱式和顯式網格的概念
隱式和顯式網格:顯式網格包含了你在 grid-template-columns
和 grid-template-rows
屬性中定義的行和列。若是你在網格定義以外又放了一些東西,或者由於內容的數量而須要的更多網格軌道的時候,網格將會在隱式網格中建立行和列
假若有多餘的網格(也就是上面提到的隱式網格),那麼它的行高和列寬能夠根據 grid-auto-columns
屬性和 grid-auto-rows
屬性設置。它們的寫法和grid-template-columns
和 grid-template-rows
徹底相同。若是不指定這兩個屬性,瀏覽器徹底根據單元格內容的大小,決定新增網格的列寬和行高
.wrapper {
display: grid;
grid-template-columns: 200px 100px;
/* 只設置了兩行,但實際的數量會超出兩行,超出的行高會以 grid-auto-rows 算 */
grid-template-rows: 100px 100px;
grid-gap: 10px 20px;
grid-auto-rows: 50px;
}
複製代碼
grid-template-columns
屬性和 grid-template-rows
屬性只是指定了兩行兩列,但實際有九個元素,就會產生隱式網格。經過 grid-auto-rows
能夠指定隱式網格的行高爲 50px
能夠指定網格項目所在的四個邊框,分別定位在哪根網格線,從而指定項目的位置
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 20px;
grid-auto-rows: minmax(100px, auto);
}
.one {
grid-column-start: 1;
grid-column-end: 2;
background: #19CAAD;
}
.two {
grid-column-start: 2;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 2;
/* 若是有重疊,就使用 z-index */
z-index: 1;
background: #8CC7B5;
}
.three {
grid-column-start: 3;
grid-column-end: 4;
grid-row-start: 1;
grid-row-end: 4;
background: #D1BA74;
}
.four {
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 2;
grid-row-end: 5;
background: #BEE7E9;
}
.five {
grid-column-start: 2;
grid-column-end: 2;
grid-row-start: 2;
grid-row-end: 5;
background: #E6CEAC;
}
.six {
grid-column: 3;
grid-row: 4;
background: #ECAD9E;
}
複製代碼
上面代碼中,類 .two
所在的網格項目,垂直網格線是從 2 到 4,水平網格線是從 1 到 2。其中它跟 .three
(垂直網格線是從3 到 4,水平網格線是從 1 到 4) 是有衝突的。能夠設置 z-index
去決定它們的層級關係
grid-area
屬性指定項目放在哪個區域,在上面介紹 grid-template-areas
的時候有提到過,這裏再也不具體展開,具體的使用能夠參考演示地址:
grid-area 以及 grid-template-areas 屬性演示地址
justify-self 屬性/ align-self 屬性/ place-self 屬性演示地址
justify-self
屬性設置單元格內容的水平位置(左中右),跟 justify-items
屬性的用法徹底一致,但只做用於單個項目
align-self
屬性設置單元格內容的垂直位置(上中下),跟align-items屬性的用法徹底一致,也是隻做用於單個項目
二者很相像,這裏只拿 justify-self
屬性演示,align-self
屬性同理,只是做用於垂直方向。place-self
是設置 align-self
和 justify-self
的簡寫形式,這裏也不重複介紹。
.item {
justify-self: start | end | center | stretch;
align-self: start | end | center | stretch;
}
複製代碼
.item {
justify-self: start;
}
.item-1 {
justify-self: end;
}
.item-2 {
justify-self: center;
}
.item-3 {
justify-self: stretch;
}
複製代碼
center:單元格內部居中
stretch:拉伸,佔滿單元格的整個寬度(默認值)
通過上面的介紹,相信你們均可以看出,Grid 是很是強大的。一些常見的 CSS 佈局,如居中,兩列布局,三列布局等等是很容易實現的。咱們接下來看看 Grid 佈局是如何實現響應式佈局的
fr
等分單位,能夠將容器的可用空間分紅想要的多個等分空間。利用這個特性,咱們可以輕易實現一個等分響應式。grid-template-columns: 1fr 1fr 1fr
表示容器分爲三等分
.wrapper {
margin: 50px;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 10px 20px;
grid-auto-rows: 50px;
}
複製代碼
等分佈局並不僅有 Grid
佈局纔有,像 flex
佈局也能輕鬆實現,接下來看看更高級的響應式
上面例子的始終都是三列的,可是需求每每但願咱們的網格可以固定列寬,並根據容器的寬度來改變列的數量。這個時候,咱們能夠用到上面提到 repeat()
函數以及 auto-fit
關鍵字。grid-template-columns: repeat(auto-fit, 200px)
表示固定列寬爲 200px,數量是自適應的,只要容納得下,就會往上排列,代碼以及效果實現以下:
.wrapper {
margin: 50px;
display: grid;
grid-template-columns: repeat(auto-fit, 200px);
grid-gap: 10px 20px;
grid-auto-rows: 50px;
}
複製代碼
上面看到的效果中,右側一般會留下空白,這是咱們不但願看到的。若是列的寬度也能在某個範圍內自適應就行了。minmax()
函數就幫助咱們作到了這點。將 grid-template-columns: repeat(auto-fit, 200px)
改爲 grid-template-columns: repeat(auto-fit, minmax(200px, 1fr))
表示列寬至少 200px,若是還有空餘則一塊兒等分。代碼以及效果以下所示:
.wrapper {
margin: 50px;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
grid-gap: 10px 20px;
grid-auto-rows: 50px;
}
複製代碼
彷佛一切進行得很順利,可是某天 UI 來講,每一個網格元素的長度可能不相同,這也簡單,經過 span
關鍵字進行設置網格項目的跨度,grid-column-start: span 3
,表示這個網格項目跨度爲 3。具體的代碼與效果以下所示:
.item-3 {
grid-column-start: span 3;
}
複製代碼
不對,怎麼右側又有空白了?原來是有一些長度太長了,放不下,這個時候就到咱們的 dense
關鍵字出場了。grid-auto-flow: row dense
表示儘量填充,而不留空白,代碼以及效果以下所示:
.wrapper, .wrapper-1 {
margin: 50px;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
grid-gap: 10px 20px;
grid-auto-rows: 50px;
}
.wrapper-1 {
grid-auto-flow: row dense;
}
複製代碼
最後,聊聊 Grid
佈局兼容性問題,在 caniuse 中,咱們能夠看到的結果以下,整體兼容性還不錯,但在 IE 10 如下不支持。我的建議在公司的內部系統運用起來是沒有問題的,但 TOC 的話,可能目前仍是不太合適
一行 CSS 代碼實現響應式佈局 – 使用 Grid 實現的響應式佈局
希望可以給你們帶來一點啓發,也歡迎你們關注個人公衆號,期待和你們一塊兒交流成長