圖解CSS布局(一)- Grid布局
先上圖
簡介
Grid 布局是將容器划分成"行"和"列",產生單元格,然后指定"項目所在"的單元格,可以看作是二維布局,也是唯一的二維布局方案,利用grid布局可以很輕松的實現很多的網頁布局
正文
gird布局很強大,采用網格布局的區域,稱為"容器"(container)。容器內部子元素,稱為"項目"(item),即container -> item
注意
:Grid 布局只對項目生效,項目只能是容器的一級子元素,不包含項目的子元素
下面從容器屬性和項目屬性兩大塊來記錄grid布局中的相關屬性
全文代碼基於
.container {
/**/
}
.item {
font-size: 50px;
color: white;
}
.item-1 {
background-color: #55efc4;
}
.item-2 {
background-color: #81ecec;
}
.item-3 {
background-color: #74b9ff;
}
.item-4 {
background-color: #a29bfe;
}
.item-5 {
background-color: #00b894;
}
.item-6 {
background-color: #0984e3;
}
.item-7 {
background-color: #6c5ce7;
}
.item-8 {
background-color: #fab1a0;
}
.item-9 {
background-color: #fdcb6e;
}
.item-10 {
background-color: #fd79a8;
}
<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 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 class="item item-10">10</div>
</div>
下面開始我們的正文
容器屬性
1. display屬性
display:grid
為一個容器采用網格布局模式
- 將元素定義為網格容器,並為其內容建立新的網格格式化上下文,屬性值有2個:
grid
:生成一個塊級網格inline-grid
:生成一個行級網格
.container {
display: grid;
/* display: inline-grid; 行級網格*/
}
在大多數場景下我們往往采用grid
塊級網格,會像塊級元素一樣占滿一行。
對於inline-grid
行級網格,它就能讓容器與其他元素共占一行,容器和行內塊元素基本一致
注意
:為網格布局以后,容器子元素(項目)的float
、display: inline-block
、display: table-cell
等設置都將失效。
左側是grid
,右側是inline-grid
2. 網格軌道
至關重要
grid-template-columns
屬性:定義每一列的列寬
grid-template-rows
屬性:定義每一行的行高
.container {
display: grid;
grid-template-columns: 200px 200px 200px;
grid-template-rows: 200px 200px 200px;
}
在上面的代碼中划分了一個三行三列,列寬和行高都是200px的網格
在這個屬性下有很多的小屬性來幫助我們優化
repeat()
當我們需要寫很多行很多列的時候,一個個敲相同的值會非常麻煩,這時候就可以使用repeat()
函數,簡化重復值
repeat()
接受兩個參數,第一個參數是重復的次數,第二個參數是所要重復的值
.container {
display: grid;
grid-template-columns: repeat(3,200px);
grid-template-rows: repeat(3,200px);
}
不止於此,repeat
還可以重復某種模式,就像
grid-template-columns: repeat(3,200px 100px);
這句代碼定義了6列,分別是200,100,200,100,200,100
還是很容易理解的,簡單說就是重復后面的值幾遍
auto-fill
關鍵字
表示自動填充,讓一行(或者一列)中盡可能的容納更多的單元格
當我們只需要確定列寬或者行高,而不用理有多少列時,就可以使用它了
.container {
display: grid;
grid-template-columns: repeat(auto-fill,200px);
grid-template-rows: repeat(3,200px);
}
每一列200px,列數設置為了auto-fill
會自動填充,此時縮小瀏覽器的寬度,項目會因填充不下而另起一行
fr
關鍵字
fr
單位代表網格容器中可用空間的一等份。使用方法如下
grid-template-columns: 200px 1fr 2fr ;
grid-template-rows: repeat(3,200px)
表示第一個列寬設置為 200px
,后面剩余的寬度分為兩部分,第二給項目占1/3
,第三個項目占2/3
從圖中可以看出第三列始終占據着剩余位置中的2份,列寬始終是第二列的二倍
minmax()
minmax()
函數產生一個長度范圍,表示長度就在這個范圍之中都可以應用到網格項目中。它接受兩個參數,分別為最小值和最大值
- 也就是說最大不會超過最大值,最小不能小過最小值
grid-template-columns: 200px 1fr minmax(400px,1fr);
grid-template-rows: repeat(3,200px)
上面的代碼 minmax(400px,1fr)
表示列寬不小於400px,不大於1fr
auto
關鍵字
設置auto
后,將由瀏覽器自行決定長度,盡可能的會占滿剩余空間,除非有其他設置,例如有min-width
之類的,利用這個關鍵字,我們可以輕易實現三列或者兩列布局。
grid-template-columns: 200px auto 200px;
grid-template-rows: repeat(3,200px)
對中間那列設置了auto,實現了中間自適應的三欄布局
- 網格線
grid布局叫做網格布局,那自然少不了網格線的存在,使用方括號,指定每一根網格線的名字,方便以后的做定位時使用
grid-template-columns: [c1] 200px [c2] auto [c3] 200px [c4];
grid-template-rows: [r1] 200px [r2] auto [r3] 200px [r4];
就像這樣定義了一個3*3
的網格區域,就需要有4條水平線,4條垂直線
3. 網格間距
row-gap
屬性設置行與行的間隔(行間距),column-gap
屬性設置列與列的間隔(列間距)。
注意
:在很多的博客中采用的都是帶有grid
前綴的方式,目前這種定義網格間距的方式已經被廢棄了,所以還是盡量采用這種寫法
.container {
grid-template-columns: repeat(3,200px);
grid-template-rows: repeat(3,200px);
row-gap: 10px;
column-gap: 10px;
}
在這段代碼中定義了行間距為10px
,列間距為10px
,也可以采用合並屬性gap
來寫gap: 10px 10px
的意思和上面相同,第一個參數是行間距,第二個是列間距
4. grid-template-areas 屬性
用於定義區域,一個區域由一個或者多個單元格組成
grid-template-columns: repeat(3, 200px);
grid-template-rows: repeat(3, 200px);
grid-template-areas: 'a b c'
'd e f'
'g h i';
上面的代碼划分出了9個單元格,然后將其命名為a~i
的9個區域,分別對應9個單元格
我們也可以將多個單元格合並成一個區域
grid-template-columns: repeat(3, 200px);
grid-template-rows: repeat(3, 200px);
grid-template-areas: 'a a a'
'b b c'
'e e c';
上面的代碼中將9個單元格划分成了a,b,c,d
4個區域
在我們常見的布局中
grid-template-areas: 'header header header'
'article article aside'
'footer footer footer';
像上面的代碼中,就划分出了4個部分,這里省略了nav
,為了和全為配一配,問題不大 :happy: 在后面會學習怎么操作這些區域,現在先了解划分區域
注意
:如果某些區域不需要利用,則用"點"(.
)表示。
就像這樣
grid-template-areas: 'a . c'
'd . f'
'g . i';
用.
占取的位置,不會被划分於任何區域,也就是在上面的代碼中,只划分了6個區域
注意
:區域的命名會影響到網格線的名字,對於區域aside
它的起始線叫做aside-start
,結束線叫做aside-end
5. grid-auto-flow 屬性
划分網格以后,容器的子元素會按照順序,自動放置在每一個網格。默認的放置順序是"先行后列",即先填滿第一行,再開始放入第二行,即下圖數字的順序。
這個順序由grid-auto-flow
屬性決定,默認值是row
,即"先行后列"。也可以將它設成column
,變成"先列后行"。
grid-auto-flow: column;
注意
:盒子的排列順序變成了先列后行
還有兩個特殊的屬性值row dense
和column dense
當我調整我們的代碼將某一個項目拉長時,會有這一行放不下的情況,就像圖片左邊這個場景一樣,第6個項目因為太長了放不上去,那個位置被空出來了,我們可以嘗試使用。
grid-auto-flow: row dense;
結果就會得到右邊的情形,7號自動的補了上去
在實際應用中,我們可能想讓下面長度合適的填滿這個空白,這個時候可以設置
grid-auto-flow: row dense
,表示盡可能填滿表格
注意
:把某個項目長度變長使用的是項目屬性,后面會寫到
6. 單元格內容排列方式
justify-items
屬性設置單元格內容的水平位置(左中右),align-items
屬性設置單元格的垂直位置(上中下)
這里只以justify-items
做展示,另一個同理,只是一個水平一個垂直的差別
- start:對齊單元格的起始邊緣。
- end:對齊單元格的結束邊緣。
- center:單元格內部居中。
- stretch:拉伸,占滿單元格的整個寬度(默認值)。
.container {
display: grid;
grid-template-columns: 200px 200px 200px;
grid-template-rows: 200px 200px 200px;
gap: 10px 10px;
justify-items: center;
}
在上面的代碼中,表示單元格內部居中
justify-items: start;
justify-items: end;
對於justify-items
和align-items
屬性,可以采用合並的寫法
place-items: start end;
代表的意思是垂直方向子項對齊起始位置,水平方向對齊結束位置
注意
:如果只寫一個值,默認第二個值與第一個相等
7. 內容區域的排列方式
justify-content
屬性是定義整個內容區域在容器里面的水平位置(左中右),align-content
屬性是定義整個內容區域的垂直位置(上中下)
有以下幾個屬性
- start :對齊容器的起始邊框。
- end :對齊容器的結束邊框。
- center :容器內部居中。
justify-content: start;
/*justify-content: center;
justify-content: end;*/
上面代碼依次從上到下對應
-
stretch :項目大小沒有指定時,拉伸占據整個網格容器。
-
space-around :每個項目兩側的間隔相等。因此,項目之間的間隔比項目與容器邊框的間隔大一倍
- space-between :項目與項目的間隔相等,項目與容器邊框之間沒有間隔。
- space-evenly :項目與項目的間隔相等,項目與容器邊框之間也是同樣長度的間隔。
8. 設置多余網格
對於網格有顯式網格和隱式網格,顯示網格通過grid-template-columns
和 grid-template-rows
屬性中定義的行和列,當實際行數或者列數大於設置的行列數時,就會有多余的網格,這些網格的寬高通過grid-auto-columns
和grid-auto-rows
屬性來設置
.container {
display: grid;
grid-template-columns: 200px 200px 200px 200px;
grid-template-rows: 200px 200px ;
gap: 10px 10px;
grid-auto-rows: 50px;
}
在上面的代碼中設置了4*2的網格,但是我們一共用9個項目,通過grid-auto-rows: 50px
設置了多余網格的高度
項目屬性
這部分是關於項目的屬性,也就是說這些屬性要寫到項目自己的身上,不能再寫到container
身上
1. 指定項目的位置
實現的原理其實是指定項目的四個邊框,分別定位在哪根網格線
grid-column-start
屬性:左邊框所在的垂直網格線grid-column-end
屬性:右邊框所在的垂直網格線grid-row-start
屬性:上邊框所在的水平網格線grid-row-end
屬性:下邊框所在的水平網格線
.container {
display: grid;
grid-template-columns: 200px 200px 200px ;
grid-template-rows: 200px 200px 200px;
gap: 10px 10px;
}
.item-1 {
background-color: #55efc4;
grid-column-start: 2;
grid-column-end: 4;
}
上面的代碼中指定了1號項目的左邊框從第二條網格線開始,第4條網格線結束,因此將會占據2個網格
也可以使用span
關鍵字,來實現占2個網格這樣的效果,可以將它理解為跨越的意思
grid-column-end: span 2;
表示的意思是:1號項目的左邊框距到右邊框跨越了2個網格。
對於上面的4個屬性可以采用簡寫的方式,例如
grid-row: 1 / 4;
grid-column: 2 / 3;
這里的/
不是除號的意思,僅是占位的作用。其中的第一行代碼,制定了上邊框在第1條網格線,下邊框在第4條網格線,第二行代碼同理。
如果只寫一個數字的話,默認跨越1個網格
注意
:當我們遇到兩個項目占據位置重疊時我們可以采用z-index
屬性確定上下關系,就像這樣
.item-1 {
background-color: #55efc4;
grid-row-start: 1;
grid-row-end: 3;
grid-column-start: 2;
grid-column-end: 4;
}
.item-3 {
grid-row: 1 / 4;
grid-column: 2 / 3;
background-color: #74b9ff;
}
給1號和3號項目添加了屬性,指定他們的占據位置,效果如左圖
給一號盒子添加了z-index:1
后,一號盒子到了上層
2. grid-area屬性
在前面容器屬性講過grid-template-areas
屬性,當時只是知道了怎么划分區域,現在這個屬性就是怎么把項目指定給區域
.container {
display: grid;
grid-template-columns: 200px 200px 200px ;
grid-template-rows: 200px 200px 200px;
grid-template-areas: 'a a a'
'b b c'
'e e c';
gap: 10px 10px;
}
首先我們先利用grid-template-areas
屬性在容器上划分區域,上面划分了4塊區域,下面我們通過給項目添加grid-area
屬性,來給它指定到某個區域當中
.item-1 {
grid-area: c;
background-color: #55efc4;
}
上面的代碼中,將1號項目指定到了c
區域,也就是右下角2個網格
注意
:2個區域之間需要緊挨,不能隔開
3. 網格內容排列方式(單個項目)
-
justify-self
屬性設置單元格內容的水平位置(左中右),跟justify-items
屬性的用法完全一致,但只作用於單個項目。 -
align-self
屬性設置單元格內容的垂直位置(上中下),跟align-items
屬性的用法完全一致,也是只作用於單個項目。
屬性值:start | end | center | stretch
從self
這個單詞來說,就有自身的意思吧(工地英語,我說有就有),也就是只對當前項目本身有效
.item-1 {
background-color: #55efc4;
justify-self: start;
/* justify-self: center;
justify-self: end;*/
}
分別對應justify-self
三個屬性值,其中stretch
拉伸會占滿網格整行
.item-1 {
background-color: #55efc4;
align-self: start;
/* align-self: center;
align-self: end; */
}
分別對應align-self
三個屬性值,其中stretch
拉伸會占滿網格整列
同樣的,存在着合並簡寫屬性place-self
,可以通過這個來指定justify-self
和align-self
的值,前后順序如下:
place-self: <align-self> <justify-self>;
以上就是關於grid
網格布局的全部內容了
Tips
grid
布局中屬性有很多,一定要通過實戰來記這些屬性,要區分好容器屬性,和項目屬性這是重中之重,多動手才是王道!
牢記此圖!