一、Grid佈局概述
首先,Grid 佈局與 Flex佈局 有一定的相似性,都可以指定容器內部多個專案的位置。但是,Grid 佈局遠比 Flex 佈局強大!
- Flex 佈局是軸線佈局,只能指定"專案"針對軸線的位置,可以看作是一維佈局。
- Grid 佈局則是將容器劃分成"行"和"列",產生單元格,然後指定"專案所在"的單元格,可以看作是二維佈局。
二、基本概念
(1)容器和專案
採用網格佈局的區域,稱為"容器"(container)。容器內部採用網格定位的子元素,稱為"專案"(item)。
<div class="container"> <div class="item"><p>1</p></div> <div class="item"><p>2</p></div> <div class="item"><p>3</p></div> </div>
上述程式碼中,如果.container
設定了display:grid
屬性,則它就是網格佈局容器 ,其內部孩子節點.item
就稱為專案
注意:專案只能是容器的頂層子元素,不包含專案的子元素,所以p
元素不是專案。Grid 佈局只對專案生效
(2)行和列
容器裡面的水平區域稱為"行"(row),垂直區域稱為"列"(column),行和列的交叉區域,稱為"單元格"(cell)
(3)網格線
劃分網格的線,稱為"網格線"(grid line)。水平網格線劃分出行,垂直網格線劃分出列。
這就是一個4行4列的網格,存在5根水平網格線和5根垂直網格線
三、容器屬性
定義在容器上面的屬性,稱為容器屬性
(1)display
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style type="text/css"> .container{ display: grid; grid-template-columns: 50px 50px; grid-template-rows: 50px 50px; border: 3px solid #9575CD; } .item { font-size: 2em; text-align: center; border: 1px solid #e5e4e9; } .item-1 { background-color: #aaaaff; } .item-2 { background-color: #1bf6d5; } .item-3 { background-color: #56a982; } .item-4 { background-color: #6072c2; } </style> </head> <body> <span>輔助元素1</span> <div class="container"> <div class="item item-1">1</div> <div class="item item-2">2</div> <div class="item item-3">3</div> <div class="item item-4">4</div> </div> <span>輔助元素2</span> </body> </html>
display: inline-grid
指定一個容器採用行內網格佈局
.container{ display: inline-grid; grid-template-columns: 50px 50px; grid-template-rows: 50px 50px; border: 3px solid #9575CD; }
特別注意:設為網格佈局以後,容器子元素(專案)的float
、display: inline-block
、display: table-cell
、vertical-align
和column-*
等設定都將失效。
.item { font-size: 2em; text-align: center; border: 1px solid #e5e4e9; float: right; /* 設定所有專案右浮動(失效) */ }
從結果可以看出,子專案並沒有右浮動到最右邊(失效)
(2)grid-template-columns 和 grid-template-rows
grid-template-columns
grid-template-rows
屬性定義每一行的行高
- 使用絕對單位劃分
.container{ display: grid; grid-template-columns: 50px 50px; /* 定義兩列,列寬為50px */ grid-template-rows: 50px 50px; /* 定義兩行,行高為50px */ border: 3px solid #9575CD; }
- 使用百分比劃分
.container{ display: grid; grid-template-columns: 20% 10%; /* 定義兩列,列寬為20% 10% */ grid-template-rows: 40% 30%; /* 定義兩行,行高為40% 30% */ border: 3px solid #9575CD; }
- repeat()函式
從上面例子可以看出,存在重複寫同樣的值,如果網格很多會顯得十分臃腫,這時可以使用
reapeat()
函式來優化
.container{ display: grid; grid-template-columns: repeat(2,150px); grid-template-rows: repeat(2,50px); }
reapeat()
函式接收兩個值,第一個值為重複次數,第二個值為需要重複的值。另外,重複某種模式也是可以的:
.container{ display: grid; grid-template-columns: repeat(2,150px 50px); }
repeat(2,150px 50px)
:表示重複了模式,定義了4列,第一列和第三列為150px
,第二列和第四列為50px
- auto-fill 關鍵字
auto-fill值用於自動填充,當單元格的大小需要固定不變,容器大小不確定時使用
.container{ display: grid; grid-template-columns: repeat(auto-fill,50px); }
repeat(auto-fill,50px)
:表示設定每列寬度為50px
自動填充,直到容器不能放置更多的列,然後換行排列(例子如下):
.container{ display: grid; width: 150px; border: 1px dashed red; grid-template-columns: repeat(auto-fill,50px); }
(換行排列)
- fr 關鍵字
fr關鍵字用於表示比例關係(fraction 的縮寫,意為"片段”)
.container{ display: grid; grid-template-columns: 1fr 5fr; }
1fr 5fr
:表示設定兩列,列寬分別為1fr
和 ,第二列是第一列的5倍
另外,fr
可以與絕對長度的單位結合使用:
.container{ display: grid; grid-template-columns:50px 1fr 2fr; }
50px 1fr 2fr
:表示第一列寬度為50px
,第二列寬度時第三列的一半
- auto 關鍵字
auto關鍵字表示由瀏覽器決定自己的長度
.container{ display: grid; grid-template-columns: 50px auto 50px auto; }
50px auto 50px auto
表示第二列和第四列自動填充,相當於flex:1
(3)row-gap 和 column-gap
row-gap
屬性設定行與行
的間隔(行間距)
column-gap
屬性設定列與列
的間隔(列間距)
.container{ display: grid; grid-template-columns: 50px 50px; grid-template-rows: 50px 50px; row-gap: 20px; /* 行間距為20px */ column-gap: 10px; /* 列間距為10px */ }
另外,這兩個屬性有個複合屬性:gap
gap語法:
gap: <row-gap> <column-gap>;
.container{ row-gap: 20px; column-gap: 10px; /* 等同於 */ gap: 20px 10px; }
注意:如果gap
只有一個值,預設第二個值等於第一個值
普及:這三個屬性名原來是由字首grid-
的,目前最新標準已經將grid-
字首刪除,但還是可以用~
(4)grid-auto-flow
劃分網格後,容器中的子元素預設按照“先行後列”的順序自動放置在每一個網格中(先填滿第一行,在開始第二行)
grid-auto-flow屬性自己規定排列順序,預設值為row
,可以設定column
,類似於flex-direction
.container{ display: grid; grid-template-columns: 50px 50px; grid-template-rows: 50px 50px; grid-auto-flow: row; /* 預設值 */ }
.container{ display: grid; grid-template-columns: 50px 50px; grid-template-rows: 50px 50px; grid-auto-flow: column; /* 先列後行 */ }
(5)justify-items 和 align-items
justify-items
屬性設定單元格內容的水平
align-items
屬性設定單元格內容的垂直
位置(上中下)
語法:
.container { justify-items: start | end | center | stretch; align-items: start | end | center | stretch; }
你沒有看錯,這兩個屬性的屬性值完全相同,都可以去這幾個值:
- start:對齊單元格的起始邊緣。
- end:對齊單元格的結束邊緣。
- center:單元格內部居中。
- stretch:拉伸,佔滿單元格的整個寬度(預設值)。
start
:單元格的內容頭部對齊:
.container{ display: grid; width: 200px; border: 1px dashed red; grid-template-columns: 100px 100px; grid-template-rows: 100px 100px; justify-items: start; }
效果如圖:
尾部對齊:
:單元格的內容.container{ display: grid; width: 200px; border: 1px dashed red; grid-template-columns: 100px 100px; grid-template-rows: 100px 100px; justify-items: end; /* 對齊單元格的結束邊緣 */ }
效果如圖:
center
:單元格內部居中:
.container{ display: grid; width: 200px; border: 1px dashed red; grid-template-columns: 100px 100px; grid-template-rows: 100px 100px; justify-items: center; /* 單元格內部居中 */ }
效果如圖:
stretch
:佔據單元格整個寬度(拉伸):
.container{ display: grid; width: 200px; border: 1px dashed red; grid-template-columns: 100px 100px; grid-template-rows: 100px 100px; justify-items: stretch; /* 預設值-拉伸佔據整個寬度 */ }
效果如圖:
這裡只演示下justify-items
屬性,對應單元格的左中右,相信大家也有點感覺了,align-items
取值是一樣的,對應的是單元格的上中下部分,這裡就不再演示了,感興趣的小夥伴自行嘗試喲
同樣,這兩個屬性也有複合屬性:place-items
語法:
place-items: <align-items> <justify-items>;
第一個值為單元格內容垂直位置,第二個值為單元格水平位置
.container{ display: grid; width: 200px; border: 1px dashed red; grid-template-columns: 100px 100px; grid-template-rows: 100px 100px; place-items: center center; /* 單元格內容水平垂直居中 */ }
效果如圖:
注意:如果省略第二個值,則預設與第一個值相等
(6)justify-content 和 align-content
justify-content
align-content
屬性是整個內容區域的垂直位置
(上中下)
注意區分justify-items 和 align-items屬性,一個是內容相對於單元格位置,一個是整個內容區域相對於父容器位置!!!
語法:
.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; }
你又沒有看錯,這兩個屬性的屬性值也是完全相同,都可以去這幾個值:
-
start - 對齊容器的起始邊框。
-
end - 對齊容器的結束邊框。
-
center - 容器內部居中。
-
stretch - 專案大小沒有指定時,拉伸佔據整個網格容器。
-
space-around - 每個專案兩側的間隔相等。所以,專案之間的間隔比專案與容器邊框的間隔大一倍。
-
space-between - 專案與專案的間隔相等,專案與容器邊框之間沒有間隔。
-
space-evenly - 專案與專案的間隔相等,專案與容器邊框之間也是同樣長度的間隔。
同樣,這裡我也只演示justify-content
屬性,align-content
屬性完全一致,只是方向不同,感興趣的小夥伴自行嘗試下啦~~
start
.container{ display: grid; width: 300px; border: 1px dashed red; grid-template-columns: 100px 100px; grid-template-rows: 100px 100px; justify-content: start;/* 對齊容器的起始邊框(預設) */ }
end
.container{ justify-content: end;/* 對齊容器的結束邊框 */ }
center
.container{ justify-content: center;/* 容器內部居中 */ }
.container{ justify-content: space-around;/* 每個專案兩側的間隔相等。專案之間的間隔比專案與容器邊框的間隔大一倍 */ }
.container{ justify-content: space-between;/* 專案與專案的間隔相等,專案與容器邊框之間沒有間隔。 */ }
space-evenly
.container{ justify-content: space-evenly;/* 專案與專案的間隔相等,專案與容器邊框之間也是同樣長度的間隔。 */ }
相信大家看完這幾個屬性值後,學過 Flex佈局 的小夥伴肯定再熟悉不過了,在flex佈局中專案與容器對齊方式也類似這幾種
同樣滴,這兩個屬性也是有複合屬性的:place-content
語法:
place-content: <align-content> <justify-content>
第一個值整個內容相對容器的垂直位置,第二個值整個內容相對容器的水平位置
.container{ display: grid; width: 300px; height: 300px; border: 1px dashed red; grid-template-columns: 100px 100px; grid-template-rows: 100px 100px; place-content: center center; /* 整體內容水平垂直居中 */ }
效果如圖:
注意:如果省略第二個值,則預設與第一個值相等
四、專案屬性
注意:專案屬性需要定義在專案上才能生效!
(1)grid-column-start、grid-column-end、grid-row-start、grid-row-end
這四個屬性是用於指定某個專案的位置,根據專案的四個邊框來定位在哪根兒網格線
-
-
grid-column-end
屬性:右邊框所在的垂直網格線 -
grid-row-start
屬性:上邊框所在的水平網格線 -
grid-row-end
下面所演示的程式碼片段也是基於前面的例子:
.container{ display: grid; width: 300px; height: 300px; border: 1px dashed red; grid-template-columns: 100px 100px; grid-template-rows: 100px 100px; } .item-1 { grid-column-start: 2;/* 開始於第二根網格線 */ grid-column-end: 4;/* 結束於第四根網格線 */ background-color: #aaaaff; }
效果如圖:
只有專案一指定了具體,其他專案自動佈局,為了便於觀察,再定位一次:
.item-1 { grid-column-start: 2;/* 垂直第一根 */ grid-column-end: 4; /* 垂直第四根 */ grid-row-start: 1;/* 水平第一根 */ grid-row-end: 3;/* 水平第三根 */ background-color: #aaaaff; }
效果如下:
這四個屬性值還可以使用span
關鍵字,表示“跨越”,就像table表格的單元格合併colspan和rowspan
.item-1 { grid-column-start: span 2;/* 橫跨兩個網格線 */ /* 等同於 */ grid-column-end: span 2;/* 橫跨兩個網格線 */ background-color: #aaaaff; }
效果如圖:
這個結果相信有些小夥伴會說其他子元素為什麼沒有在第一個子元素之後繼續排列?
我想說的是grid-template-columns: 100px 100px;
我只設定了兩列,如果改成grid-template-columns: 100px 100px 100px;
這樣,那容器剩餘的空間就可以補齊啦~
注意:使用這四個屬性,如果產生了專案的重疊,則使用z-index
屬性指定專案的重疊順序
(2)grid-column 和 grid-row
grid-row:
grid-row-start
屬性和grid-row-end
語法:
.item { grid-column: <start-line> / <end-line>; grid-row: <start-line> / <end-line>; }
來個栗子:
.item-1 { grid-column: 1 / 3; /* 佔據水平方向上的第1根和第3根 */ grid-row: 2 / 4; /* 佔據垂直方向上的第2根和第4根 */ background-color: #aaaaff; }
效果如圖:
注意:斜槓以及後面的部分可以省略,預設跨越一個網格
(3)justify-self 和 align-self
justify-self
屬性設定單元格內容的水平位置(左中右),跟justify-items
align-self
屬性設定單元格內容的垂直位置(上中下),跟align-items
屬性的用法完全一致,也是隻作用於單個專案。
語法:
.item { justify-self: start | end | center | stretch; align-self: start | end | center | stretch; }
取值:
-
-
end:對齊單元格的結束邊緣。
-
center:單元格內部居中。
-
.item-1 { justify-self: start; /* 指定專案單元格左對齊 */ background-color: #aaaaff; }
這裡我就演示一個就行了,其他都一樣,有手就行,大家可以自行嘗試下
place-self
屬性是align-self
屬性和justify-self
屬性的合併簡寫形式
語法:
place-self: <align-self> <justify-self>;
例子:
.item-1 { place-self: center center; background-color: #aaaaff; }