網(wǎng)格布局(Grid)
它將網(wǎng)頁劃分成一個(gè)個(gè)網(wǎng)格绩聘,可以任意組合不同的網(wǎng)格,做出各種各樣的布局疼阔。以前,只能通過復(fù)雜的 CSS 框架達(dá)到的效果半夷,現(xiàn)在瀏覽器內(nèi)置了婆廊。
Grid 布局與 Flex 布局有一定的相似性,都可以指定容器內(nèi)部多個(gè)項(xiàng)目的位置巫橄。但是淘邻,它們也存在重大區(qū)別。
Flex 布局是軸線布局湘换,只能指定"項(xiàng)目"針對(duì)軸線的位置宾舅,可以看作是一維布局统阿。Grid 布局則是將容器劃分成"行"和"列",產(chǎn)生單元格筹我,然后指定"項(xiàng)目所在"的單元格扶平,可以看作是二維布局。Grid 布局遠(yuǎn)比 Flex 布局強(qiáng)大蔬蕊。
比如 flex布局中兩側(cè)對(duì)齊结澄,最后一排,如果元素不夠岸夯,則左對(duì)齊麻献。flex中往往采用生成一個(gè)元素,頁面不可見實(shí)現(xiàn)猜扮,而grid布局則可以簡(jiǎn)單的實(shí)現(xiàn)勉吻。
瀏覽器兼容性
很多人總覺得 CSS Grid 的兼容性不行。其實(shí)不然旅赢,下圖的統(tǒng)計(jì)數(shù)據(jù)能夠看出大部分瀏覽器對(duì) CSS Grid 的支持還是不錯(cuò)的餐曼,要知道 Flex 在 IE10 上面可以使用的屬性也非常有限。據(jù)統(tǒng)計(jì)目前 CSS Grid 使用率和 Flex 已經(jīng)基本持平了鲜漩。所以兼容性并不能回答開篇提出的問題源譬。
基本概念
1.容器---有容器屬性(container) 和 項(xiàng)目---有項(xiàng)目屬性(items)
采用網(wǎng)格布局的區(qū)域,稱為"容器"(container)孕似。容器內(nèi)部采用網(wǎng)格定位的子元素踩娘,稱為"項(xiàng)目"(item)。
<div>
<div><p>1</p></div>
<div><p>2</p></div>
<div><p>3</p></div>
</div>
上面代碼中喉祭,最外層的<div>元素就是容器养渴,內(nèi)層的三個(gè)<div>元素就是項(xiàng)目。
注意:項(xiàng)目只能是容器的頂層子元素泛烙,不包含項(xiàng)目的子元素理卑,比如上面代碼的<p>元素就不是項(xiàng)目。Grid 布局只對(duì)項(xiàng)目生效蔽氨。
-
行和列
容器里面的水平區(qū)域稱為"行"(row)藐唠,垂直區(qū)域稱為"列"(column)。
image.png
水平的深色區(qū)域就是"行"鹉究,垂直的深色區(qū)域就是"列"宇立。
- 單元格
行和列的交叉區(qū)域,稱為"單元格"(cell)自赔。
正常情況下妈嘹,n行和m列會(huì)產(chǎn)生n x m個(gè)單元格。比如绍妨,3行3列會(huì)產(chǎn)生9個(gè)單元格润脸。
- 網(wǎng)格線
劃分網(wǎng)格的線柬脸,稱為"網(wǎng)格線"(grid line)。水平網(wǎng)格線劃分出行毙驯,垂直網(wǎng)格線劃分出列倒堕。
正常情況下,n行有n + 1根水平網(wǎng)格線尔苦,m列有m + 1根垂直網(wǎng)格線涩馆,比如三行就有四根水平網(wǎng)格線。
上圖是一個(gè) 4 x 4 的網(wǎng)格允坚,共有5根水平網(wǎng)格線和5根垂直網(wǎng)格線魂那。
容器屬性
Grid 布局的屬性分成兩類。一類定義在容器上面稠项,稱為容器屬性
涯雅;另一類定義在項(xiàng)目上面,稱為項(xiàng)目屬性
展运。這部分先介紹容器屬性活逆。
display 屬性
display: grid指定一個(gè)容器采用網(wǎng)格布局。
grid-template-columns 屬性拗胜,grid-template-rows 屬性
容器指定了網(wǎng)格布局以后蔗候,接著就要?jiǎng)澐中泻土小rid-template-columns屬性定義每一列的列寬埂软,grid-template-rows屬性定義每一行的行高
<div class="box">
<div>
<p>1</p>
</div>
<div>
<p>2</p>
</div>
<div>
<p>3</p>
</div>
<div>
<p>4</p>
</div>
<div>
<p>5</p>
</div>
<div>
<p>6</p>
</div>
<div>
<p>7</p>
</div>
<div>
<p>8</p>
</div>
</div>
.box {
display: grid;
grid-template-columns: 50px 100px 100px;
grid-template-rows: 100px 100px 150px;
}
div {
border: 1px solid #f00;
margin: 5px;
}
repeat()
有時(shí)候锈遥,重復(fù)寫同樣的值非常麻煩,尤其網(wǎng)格很多時(shí)勘畔。這時(shí)所灸,可以使用repeat()函數(shù),簡(jiǎn)化重復(fù)的值炫七。上面的代碼用repeat()改寫如下爬立。
.box {
display: grid;
grid-template-columns: repeat(3, 100px);
grid-template-rows: 100px 100px 150px;
}
div {
border: 1px solid #f00;
margin: 5px;
}
auto-fill 關(guān)鍵字
有時(shí),單元格的大小是固定的万哪,但是容器的大小不確定侠驯。如果希望每一行(或每一列)容納盡可能多的單元格,這時(shí)可以使用auto-fill關(guān)鍵字表示自動(dòng)填充壤圃。
.box {
display: grid;
grid-template-columns: repeat(auto-fill, 100px);
grid-template-rows: 100px 100px 150px;
}
div {
border: 1px solid #f00;
margin: 5px;
}
fr 關(guān)鍵字
為了方便表示比例關(guān)系陵霉,網(wǎng)格布局提供了fr關(guān)鍵字(fraction 的縮寫,意為"片段")伍绳。如果兩列的寬度分別為1fr和2fr,就表示后者是前者的兩倍乍桂。
.box{
grid-template-columns: 1fr 2fr 1fr 1fr;
grid-template-rows: 100px 100px 150px;
}
div {
border: 1px solid #f00;
margin: 5px;
}
minmax()
minmax()函數(shù)產(chǎn)生一個(gè)長(zhǎng)度范圍冲杀,表示長(zhǎng)度就在這個(gè)范圍之中效床。它接受兩個(gè)參數(shù),分別為最小值和最大值权谁。
.box{
grid-template-columns: 1fr 1fr minmax(100px, 1fr);
grid-template-rows: 100px 100px 150px;
}
div {
border: 1px solid #f00;
margin: 5px;
}
auto 關(guān)鍵字
auto關(guān)鍵字表示由瀏覽器自己決定長(zhǎng)度剩檀。
.box{
grid-template-columns: 100px auto 100px;
grid-template-rows: 100px 100px 150px;
}
div {
border: 1px solid #f00;
margin: 5px;
}
網(wǎng)格線的名稱
grid-template-columns屬性和grid-template-rows屬性里面,還可以使用方括號(hào)旺芽,指定每一根網(wǎng)格線的名字沪猴,方便以后的引用。
.container {
display: grid;
grid-template-columns: [c1] 100px [c2] 100px [c3] auto [c4];
grid-template-rows: [r1] 100px [r2] 100px [r3] auto [r4];
}
上面代碼指定網(wǎng)格布局為3行 x 3列采章,因此有4根垂直網(wǎng)格線和4根水平網(wǎng)格線运嗜。方括號(hào)里面依次是這八根線的名字。
網(wǎng)格布局允許同一根線有多個(gè)名字悯舟,比如[fifth-line row-5]担租。
布局實(shí)例
grid-template-columns屬性對(duì)于網(wǎng)頁布局非常有用。兩欄式布局只需要一行代碼抵怎。
.wrapper {
display: grid;
grid-template-columns: 70% 30%;
}
grid-row-gap 屬性奋救,grid-column-gap 屬性,grid-gap 屬性
grid-row-gap屬性設(shè)置行與行的間隔(行間距)反惕,grid-column-gap屬性設(shè)置列與列的間隔(列間距)尝艘。
grid-gap屬性是grid-column-gap和grid-row-gap的合并簡(jiǎn)寫形式,語法如下姿染。
grid-gap: <grid-row-gap> <grid-column-gap>;
.box {
display: grid;
grid-template-columns: repeat(3, 100px);
grid-template-rows: 100px 100px 150px;
grid-row-gap: 10px;
grid-column-gap: 20px;
}
div {
border: 1px solid #f00;
}
grid-template-areas 屬性
網(wǎng)格布局允許指定"區(qū)域"(area)背亥,一個(gè)區(qū)域由單個(gè)或多個(gè)單元格組成。grid-template-areas屬性用于定義區(qū)域盔粹。
.container {
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
grid-template-areas: 'a b c'
'd e f'
'g h i';
}
面代碼先劃分出9個(gè)單元格隘梨,然后將其定名為a到i的九個(gè)區(qū)域,分別對(duì)應(yīng)這九個(gè)單元格舷嗡。
grid-auto-flow 屬性
劃分網(wǎng)格以后轴猎,容器的子元素會(huì)按照順序,自動(dòng)放置在每一個(gè)網(wǎng)格进萄。默認(rèn)的放置順序是"先行后列"捻脖,即先填滿第一行,再開始放入第二行中鼠,即下圖數(shù)字的順序可婶。
這個(gè)順序由grid-auto-flow屬性決定,默認(rèn)值是row援雇,即"先行后列"矛渴。也可以將它設(shè)成column,變成"先列后行"。
grid-auto-flow: column;
justify-items 屬性具温,align-items 屬性蚕涤,place-items 屬性
justify-items屬性設(shè)置單元格內(nèi)容的水平位置(左中右),align-items屬性設(shè)置單元格內(nèi)容的垂直位置(上中下)铣猩。
.container {
justify-items: start | end | center | stretch;
align-items: start | end | center | stretch;
}
start:對(duì)齊單元格的起始邊緣揖铜。
end:對(duì)齊單元格的結(jié)束邊緣。
center:?jiǎn)卧駜?nèi)部居中达皿。
stretch:拉伸天吓,占滿單元格的整個(gè)寬度(默認(rèn)值)。
place-items屬性是align-items屬性和justify-items屬性的合并簡(jiǎn)寫形式峦椰。
place-items: <align-items> <justify-items>;
justify-content 屬性龄寞,align-content 屬性,place-content 屬性
justify-content屬性是整個(gè)內(nèi)容區(qū)域在容器里面的水平位置(左中右)们何,align-content屬性是整個(gè)內(nèi)容區(qū)域的垂直位置(上中下)萄焦。
.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;
}
下面實(shí)現(xiàn) 左右兩側(cè)對(duì)齊,最后一排元素不足冤竹,左對(duì)齊
.box {
display: grid;
justify-content: space-between;
grid-template-columns: repeat(3, 100px);
grid-template-rows: 100px 100px 150px;
grid-row-gap: 10px;
grid-column-gap: 20px;
}
div {
border: 1px solid #f00;
}
grid-auto-columns 屬性拂封,grid-auto-rows 屬性
有時(shí)候,一些項(xiàng)目的指定位置鹦蠕,在現(xiàn)有網(wǎng)格的外部瓢湃。比如網(wǎng)格只有3列蒲跨,但是某一個(gè)項(xiàng)目指定在第5行腥沽。這時(shí)姑子,瀏覽器會(huì)自動(dòng)生成多余的網(wǎng)格,以便放置項(xiàng)目肠阱。
grid-auto-columns
屬性和grid-auto-rows
屬性用來設(shè)置票唆,瀏覽器自動(dòng)創(chuàng)建的多余網(wǎng)格的列寬和行高。它們的寫法與grid-template-columns
和grid-template-rows
完全相同屹徘。如果不指定這兩個(gè)屬性走趋,瀏覽器完全根據(jù)單元格內(nèi)容的大小,決定新增網(wǎng)格的列寬和行高噪伊。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div id="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 class="item item-5">5</div>
<div class="item item-6">6</div>
<div class="item item-7">7</div>
<div class="item item-8">8</div>
<div class="item item-9">9</div>
</div>
</body>
</html>
#container{
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
grid-auto-rows: 50px;
}
.item {
font-size: 2em;
text-align: center;
border: 1px solid #e5e4e9;
}
.item-1 {
background-color: #ef342a;
}
.item-2 {
background-color: #f68f26;
}
.item-3 {
background-color: #4ba946;
}
.item-4 {
background-color: #0376c2;
}
.item-5 {
background-color: #c077af;
}
.item-6 {
background-color: #f8d29d;
}
.item-7 {
background-color: #b5a87f;
}
.item-8 {
background-color: #d0e4a9;
grid-row-start: 4;
grid-column-start: 2;
}
.item-9 {
background-color: #4dc7ec;
grid-row-start: 5;
grid-column-start: 3;
}
上面代碼指定新增的行高統(tǒng)一為50px(原始的行高為100px)簿煌。
grid-template 屬性,grid 屬性
grid-template
屬性是grid-template-columns鉴吹、grid-template-rows和grid-template-areas這三個(gè)屬性的合并簡(jiǎn)寫形式姨伟。
grid
屬性是grid-template-rows、grid-template-columns豆励、grid-template-areas夺荒、 grid-auto-rows、grid-auto-columns、grid-auto-flow這六個(gè)屬性的合并簡(jiǎn)寫形式般堆。
從易讀易寫的角度考慮在孝,還是建議不要合并屬性诚啃,所以這里就不詳細(xì)介紹這兩個(gè)屬性了淮摔。
項(xiàng)目屬性
下面這些屬性定義在項(xiàng)目上面。
grid-column-start 屬性始赎,grid-column-end 屬性和橙,grid-row-start 屬性,grid-row-end 屬性
項(xiàng)目的位置是可以指定的造垛,具體方法就是指定項(xiàng)目的四個(gè)邊框魔招,分別定位在哪根網(wǎng)格線。
grid-column-start屬性:左邊框所在的垂直網(wǎng)格線
grid-column-end屬性:右邊框所在的垂直網(wǎng)格線
grid-row-start屬性:上邊框所在的水平網(wǎng)格線
grid-row-end屬性:下邊框所在的水平網(wǎng)格線
.item-1 {
grid-column-start: 2;
grid-column-end: 4;
}
上面代碼指定五辽,1號(hào)項(xiàng)目的左邊框是第二根垂直網(wǎng)格線办斑,右邊框是第四根垂直網(wǎng)格線。
只指定了1號(hào)項(xiàng)目的左右邊框杆逗,沒有指定上下邊框乡翅,所以會(huì)采用默認(rèn)位置,即上邊框是第一根水平網(wǎng)格線罪郊,下邊框是第二根水平網(wǎng)格線蠕蚜。
除了1號(hào)項(xiàng)目以外,其他項(xiàng)目都沒有指定位置悔橄,由瀏覽器自動(dòng)布局靶累,這時(shí)它們的位置由容器的grid-auto-flow屬性決定,這個(gè)屬性的默認(rèn)值是row癣疟,因此會(huì)"先行后列"進(jìn)行排列挣柬。讀者可以把這個(gè)屬性的值分別改成column、row dense和column dense睛挚,看看其他項(xiàng)目的位置發(fā)生了怎樣的變化邪蛔。
grid-column 屬性,grid-row 屬性
grid-column
屬性是grid-column-start和grid-column-end的合并簡(jiǎn)寫形式竞川,grid-row
屬性是grid-row-start屬性和grid-row-end的合并簡(jiǎn)寫形式店溢。
.item {
grid-column: <start-line> / <end-line>;
grid-row: <start-line> / <end-line>;
}
grid-area 屬性
grid-area屬性指定項(xiàng)目放在哪一個(gè)區(qū)域。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div id="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 class="item item-5">5</div>
<div class="item item-6">6</div>
<div class="item item-7">7</div>
<div class="item item-8">8</div>
<div class="item item-9">9</div>
</div>
</body>
</html>
#container{
display: grid;
grid-template-columns: 100px 100px 100px;
grid-template-rows: 100px 100px 100px;
grid-template-areas: 'a b c'
'd e f'
'g h i';
}
.item {
font-size: 4em;
text-align: center;
border: 1px solid #e5e4e9;
}
.item-1 {
background-color: #ef342a;
grid-area: e;
}
.item-2 {
background-color: #f68f26;
}
.item-3 {
background-color: #4ba946;
}
.item-4 {
background-color: #0376c2;
}
.item-5 {
background-color: #c077af;
}
.item-6 {
background-color: #f8d29d;
}
.item-7 {
background-color: #b5a87f;
}
.item-8 {
background-color: #d0e4a9;
}
.item-9 {
background-color: #4dc7ec;
}
grid-area
屬性還可用作grid-row-start委乌、grid-column-start床牧、grid-row-end、grid-column-end的合并簡(jiǎn)寫形式遭贸,直接指定項(xiàng)目的位置戈咳。
grid-area: <row-start> / <column-start> / <row-end> / <column-end>;
justify-self 屬性,align-self 屬性,place-self 屬性
justify-self
屬性設(shè)置單元格內(nèi)容的水平位置(左中右)著蛙,跟justify-items屬性的用法完全一致删铃,但只作用于單個(gè)項(xiàng)目。
align-self
屬性設(shè)置單元格內(nèi)容的垂直位置(上中下)踏堡,跟align-items屬性的用法完全一致猎唁,也是只作用于單個(gè)項(xiàng)目。
.item {
justify-self: start | end | center | stretch;
align-self: start | end | center | stretch;
}
start:對(duì)齊單元格的起始邊緣顷蟆。
end:對(duì)齊單元格的結(jié)束邊緣诫隅。
center:?jiǎn)卧駜?nèi)部居中。
stretch:拉伸帐偎,占滿單元格的整個(gè)寬度(默認(rèn)值)逐纬。
place-self
place-self屬性是align-self屬性和justify-self屬性的合并簡(jiǎn)寫形式
place-self: <align-self> <justify-self>;
參考:https://www.ruanyifeng.com/blog/2019/03/grid-layout-tutorial.html
https://zhuanlan.zhihu.com/p/279972433
http://www.reibang.com/p/3762f214cd6f