一、初識Grid布局
網格布局(Grid)是強大的CSS布局方案,它將網頁划分為一個個的網格,通過任意組合這些網格來實現不同需求的布局方式。
上圖這種布局,Grid可以輕松的實現(代碼量少)
Grid布局與Flex布局的相似處:
都是容器 + 項目,都是可以指定項目在容器內部的位置。
Grid布局與Flex布局的不同處:
Flex布局是軸線布局,只能指定項目針對軸線的位置;Grid布局則是將容器分成行和列,生成單元格,然后指定項目的單元格,Grid布局更靈活更強大。
二、基本概念
1、容器與項目
采用Grid布局的區域(標簽),成為“容器”(container),容器內部采用的網格定位的子元素,稱為“項目”(item)。需要特別注意的是只有容器的子元素才能視為“項目”,孫子元素不能視為容器的項目。Grid布局只對項目生效。
2、行、列、單元格、網格線
1)行:容器里面的水平區域稱為“行”(row);
2)列:垂直區域稱為“列”(column);
3)單元格:行和列交叉區域稱為“單元格”(cell);
單元格計算:正常情況下,n行和m列,會產生 n * m 個單元格
4)網格線:划分網格的線稱為“網格線”(grid line);
水平網格線划分出行,垂直網格線划分出列。
網格線計算:正常情況下,n行有 n + 1 根水平網格線,m列有 m + 1 根垂直網格線
上圖標記了對應的行、列、單元格、網格線
三、容器屬性
1、display
指定一個標簽為網格布局的容器
div { display: grid| line-grid; }
注意⚠️:設置為網格布局后,容器項目(item)的float、dispaly: inline-block、display:table-cell、vertical-align和column-* 等設置都會失效
2、grid-template-columns/grid-template-rows屬性
容器指定了Grid布局之后,我們就要對行和列進行划分。grid-template-columns 屬性定義每一列的列寬,grid-template-rows 屬性定義了每一行的行高。
屬性值:
1)固定值
.container { display: grid; grid-template-columns: 200px 100px 100px; grid-template-rows: 100px 200px 100px; line-height: 100px; }
效果圖:
2)百分比
3)repeat()
當網格很多的時候,需要重復寫同樣的值,不方便,可以使用repeat()函數,簡化重復的值。上面的代碼可以用repeat()改寫如下:頁面效果相同
.container { display: grid; grid-template-columns: 200px repeat(2,100px); grid-template-rows: 100px 200px 100px; line-height: 100px; }
repeat函數接受兩個參數,第一個參數是重復的次數(重復次數設置2次),第二個參數是所要重復的值(重復值可以設置多個 100px 200px 300px(一共是6列2*3))。
a、auto-fill 關鍵字:repeat函數還可以使用關鍵字 auto-fill
有時候單元格的大小是固定的,但是容器的大小不確定。如果希望每一行|每一列容納盡可能多的單元格,這時可以使用auto-fill關鍵字表示自動填充。
.container { display: grid; grid-template-columns: repeat(auto-fill, 100px); line-height: 100px; }
效果圖:
b、fr關鍵字:
為了方便表示比例關系,網格布局提供了fr關鍵字。如果兩列的寬度分別是1fr和2fr,就表示后者是前者的兩倍。
.container { display: grid; grid-template-columns: 1fr 2fr; line-height: 100px; }
效果圖:
fr可以與絕對長度的單位結合使用,這時會非常方便
.container { display: grid; grid-template-columns:50px 1fr 2fr; line-height: 100px; }
效果圖:
c、minmax() :
minmax函數產生一個長度范圍,表示長度就在這個范圍之中。它接受兩個參數,分別為最小值和最大值。
d、auto關鍵字
auto關鍵字表示由瀏覽器自己決定長度。
.container { display: grid; grid-template-columns:100px auto 200px; line-height: 100px; }
效果圖:
上面的代碼實現了左右兩列寬度固定,中間自適應
e、網格線的名稱
grid-template-columns 屬性和grid-template-rows 屬性,可以使用方括號指定每一根網格線的名字,方便以后的引用。
.container { display: grid; grid-template-columns:[c1] 100px [c2] auto [c3] 200px [c4]; grid-template-rows:[r1] 100px [r2] 100px [r3] 100px [r4]; line-height: 100px; }
上面代碼定義了3*3網格的八根網格線的名字。網格布局允許同一根線有多個名字,比如[r1-1 r1-2]
。
3、row-gap/column-gap/gap屬性
row-gap屬性設置行與行之間的間隔;column-gap屬性設置列與列之間的間隔
.container { display: grid; grid-template-columns:[c1] 100px [c2] auto [c3] 200px [c4]; grid-template-rows:[r1] 100px [r2] 100px [r3] 100px [r4]; line-height: 100px; row-gap: 10px; column-gap: 30px; }
效果圖:
gap屬性是row-gap屬性與column-gap屬性的合並簡寫形式(只設置一個值時,row、column值相同)。
.container { display: grid; grid-template-columns:[c1] 100px [c2] auto [c3] 200px [c4]; grid-template-rows:[r1] 100px [r2] 100px [r3] 100px [r4]; line-height: 100px; gap: 10px 30px;//與下面兩句代碼等價 /* row-gap: 10px; column-gap: 30px; */ }
4、grid-template-areas 屬性
網格布局允許指定“區域”(area),一個區域由多個或單個單元格組成
.container { display: grid; grid-template-columns:[c1] 100px [c2] auto [c3] 200px [c4]; grid-template-rows:[r1] 100px [r2] 100px [r3] 100px [r4]; line-height: 100px; grid-template-areas: 'a b c' 'd e f' 'g h i'; }
上面代碼將網格划分了9個單元格,然后將這些單元格按a到i依次命名,即9個區域有自己的名字。
一個區域由多個單元格組成的情況:
.container { display: grid; grid-template-columns:[c1] 100px [c2] auto [c3] 200px [c4]; grid-template-rows:[r1] 100px [r2] 100px [r3] 100px [r4]; line-height: 100px; grid-template-areas: 'a a a' 'b b b' 'c c c'; }
上面代碼將9個單元格分成了以 a、b、c為名字的三個區域。
如果某些單元格不需要划分區域,那么這些單元格以(.)表示
grid-template-areas: 'a . a' 'b b b' 'c . c';
注意⚠️:區域的命名會影響到網格線。每個區域的起始網格線,會自動命名為 區域名-start
,終止網格線自動命名為 區域名-end
。
5、grid-auto-flow 屬性
設置子元素在容器中排列方式是“先行后列” row;還是“先列后行”column。
.container { display: grid; grid-template-columns:[c1] 100px [c2] auto [c3] 200px [c4]; grid-template-rows:[r1] 100px [r2] 100px [r3] 100px [r4]; line-height: 100px; grid-template-areas: 'a a a' 'b b b' 'c c c'; grid-auto-flow: column; }
效果圖:
.container { display: grid; grid-template-columns:[c1] 100px [c2] auto [c3] 200px [c4]; grid-template-rows:[r1] 100px [r2] 100px [r3] 100px [r4]; line-height: 100px; grid-template-areas: 'a a a' 'b b b' 'c c c'; grid-auto-flow: row; }
效果圖:
grid-auto-flow
屬性除了設置成row
和column
,還可以設成row dense
和column dense
。這兩個值主要用於,某些項目指定位置以后,剩下的項目怎么自動放置。
6、justify-items/align-items/place-items 屬性
justify-items 屬性設置單元格內容的水平位置;align-items 屬性設置單元格內容的垂直位置 。
justify-items: start | end | center | stretch(默認值,拉伸,占滿整個單元格的寬度);
align-items: start | end | center | stretch(默認值,拉伸,占滿整個單元格的寬度);
place-items 屬性是justify-items和align-items屬性的合並簡寫形式
place-items: <align-items> <justify-items>;
如果只設置一個值,那么兩個值設置為相等值
7、justify-content/align-content/place-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為例
justify-content:satrt;//對齊容器的起始邊框
效果圖
justify-content: center;//容器內部居中
效果圖
justify-content: end;//對齊容器的結束邊框
效果圖
justify-content: stretch;項目大小沒有指定時,拉伸占據整個網格容器
justify-content: space-around;//每個項目兩側的間隔相等。所以項目之間的間隔比項目與容器邊框的間隔大一倍
效果圖