簡介
? ? CSS Grid Layout(下文稱 “Grid”)是一個非常強大的雙維度布局方式,目的在于消除之前通過tables,floats,positioning和inlne-block這種比較hacks的方法布局。它的語法與flexbox十分相似,但比起flexbox只能確定一個維度的布局方式(縱向,或者橫向),grid可以同時確定橫向和縱向的布局。


幾種術(shù)語
? ? 在正式介紹Grid之前,先了解一下里面提到的幾種概念。
?Grid Container
? ????一個即將進行Grid布局的容器,被 display: grid /grid-line?定義的標(biāo)簽,是Grid Items的直接父級,下面的例子中,<div class=" container "> 是一個 grid container。

Grid Item
????是grid container的直接子集,如下圖,<div class=" item " >是container的grid items,但是 <p class=" sub-item ">不是

Grid Line
????grid line可以理解為是對grid container進行劃分的線,可以橫向劃分也可以縱向劃分,如下圖所示,黃色的線是一條grid line:

Grid Track
????由兩條相鄰的grid line圍起來的區(qū)域就是grid track,如下圖所示,黃色的陰影部分是一個gri track:

Grid Cell
????被grid line切割完后的小區(qū)域塊,又四條響鈴的grid line圍成,像表格里的單元格一樣,如下圖所示,黃色的區(qū)域是一個grid cell:

Grid Area
????由四條grid line(不要求相鄰)圍起來的區(qū)域,每個area可以包含1 - n個cell,如下圖黃色區(qū)域所示:

屬性
?????Grid與flex一樣,屬性也分容器(grid container)屬性和元素(grid items)屬性,在布局時,也需要同時對父元素和子元素進行操作。
item的屬性:
Note: float,display:inline-block / table-cell,vertical-align和column-*這些屬性對grid item無效。
grid-column-start/grid-column-end/grid-row-start/grid-row-end:
????定義一個item(grid area)由哪四條grid line圍起來的。值可以是?line的名字,也可以是?編號,或者?auto,auto會自動計算劃分的范圍。
? ? 如果不設(shè)定 grid-column-end / grid-row-end,那么默認向前衍生一個track。同時,多個items可以互相重疊,可以用 z-index 來決定疊加順序。
????在line名字相同的情況下,我們寫line名字的時候除了指定名字,還需要指定是該名稱下的第幾個line:.item{ grid-column-start: col-start 2;}


grid-column/grid-row:
????grid-column-start,grid-column-end,grid-row-start,grid-row-end的簡寫模式。值可以是具體的line,也可以是跨越的track的數(shù)(span value)。
????grid-column/row : <start-line> / <end-line> | <start-line> / span <value>
grid-area:
? ? 為一個grid area取一個名字,這樣可以被 container 屬性 grid-template-areas 引用。也可以作為上述四個屬性的簡寫。
????grid-area:name | row-star t/ column-start / row-end /column-end
justify-self 與 align-self:
????定義item在一個cell中行 列顯示的位置。也可以在 container 屬性 justify-items?/ align-items中被定義。值有:
????start:從cell的開始開始填充
????end:從cell的結(jié)束開始填充
????center:在cell的中間
????stretch:縮放item使他填充整個cell,默認屬性。







place-self:
????align-self 和 justify-self 的縮寫模式
????place -self : <value> 同時被align和justify應(yīng)用 | <align-self> <justify-self>
container的屬性:
display:
????定義一個Grid Container,建立一個新的?grid formatting context 上下文環(huán)境,可以有兩種取值:
? ??????grid:定義一個block-level grid?
? ??????inline-grid:定義一個inline-level container
grid-template-columns與grid-template-rows:
? ? grid-template-colunms/rows:[line-one-name1 line-one-name2 ...] size ...
????設(shè)置grid line的分隔空間,注意,每條line可以有多個名字。size可以是一個數(shù)字長度,也可以是百分數(shù),還可以設(shè)置成auto來自動填充大小,多個auto可以通過單位 fr 來按照 分數(shù) 比例劃分。比如:.container{ grid-template-columns: 1fr 50px 1fr 1fr},會在container下將50px減去后,在除以三就是每line之間的寬度。比如:
grid-template-columns: [first] 40px [line2] 50px [line3] auto [col4-start] 50px [five] 40px [end];?
grid-template-rows: [row1-start] 25% [row1-end] 100px [third-line] auto [last-line];

? ? 其中,如果定義的空間都是一樣和重復(fù)的,可以使用replace()函數(shù)來代替繁瑣的定義。
????.container{ grid-template-columns: repeat(3, 20px [col-start]);}
????這句話等價于:
????.container{ grid-template-columns: [col-start] 20px [col-start] 20px [col-start] 20px;},
grid-template-areas:
????定義grid container的組織結(jié)構(gòu),通過使用由 grid-area 屬性定義的grid areas,來填充container,值可以是:
????grid-area-name:一個grid-area。
????. :代表一個空grid cell,可以使用幾個連續(xù)的 ... 來表示這里有好幾個空cell。
?????none:grid area沒有被定義。
????雖然這個屬性不是用來定義line的名字的,但是在將一個已經(jīng)命名的area放進container后,包裹他的line將自動產(chǎn)生新的名字。比如定義了一個叫 header 的區(qū)域,那么包裹他的column-start和row-start將命名為:header-start,column-end和row-end將命名為:header-end。


grid-template:
? ? ?是 grid-template-rows,grid-template-columns,grid-template-areas?的簡寫模式,從上到下開始定義,下面兩種寫法是等價的:


grid-column-gap/grid-row-gap:
? ? 設(shè)置line的粗細,可以想象是在設(shè)置columns/rows的間隔:只是設(shè)定行與行,列與列間的間隔,并不會影響邊界。
grid-column-gap:<line-size>

grid-gap:
????grid-row-gap 和grid-column-gap 的簡寫模式。
? ? grid-gap:<grid-row-gap> <grid-column-gap>
justify-items 與 align-items:
????統(tǒng)一指定container下所有items的 justify-self 或 align-self,可以取的值與item的justify-self / align-self 相同,示例如下:








place-items:
????align-items和 justity-items 的簡寫模式。
????place-items:<align-items> / <justify-items>
justify-content 與 align-content
????有的時候你的整個grid會比container小,這種情況一般發(fā)生在所有的items都用了非彈性的單位來指定大?。ū热?px),這個時候你可以通過設(shè)置justify-content(行)與align-content(列)來確定grid在grid-content的排布方式。值和例子分別如下:
????start:從container的開始填充


????end:從container的結(jié)尾填充


? ? center:從container的中間


? ? stretch:縮放使得完全填充滿container的寬度(justify-content)/高度(align-content)


? ? space-around:為每一列/行會平均分配空隙,邊緣處的空隙只有中間的一半,相當(dāng)于給每一 列/行平均設(shè)置margin。


? ? space-between:為每一列/行會平均分配空隙,邊緣處不設(shè)置空隙。


? ? space-evenly:為每一列/行會平均分配空隙,邊緣處的空隙與中間一樣。


place-content:
? ? align-content 與 justify-content的簡寫模式:
????place-content:<align-content> / <justify-content>
grid-auto-columns/grid-auto-rows:
? ? 為一些自動生成的grid tracks(又稱為隱形tracks)指定大小。一般這種情況發(fā)生在你的grid items比cells還要多,或者指定了一個超出邊界的grid item的時候,值可以是?數(shù)字,百分比,或者有 fr 定義的分數(shù)。
????下面解釋一下隱形tracks的產(chǎn)生情況:
????.container{ grid-template-columns: 60px 60px; grid-template-rows: 90px 90px}?。生成如下2*2 的container:

這個時候想象一下有一個item你是這樣定位的:
????.item-a{ grid-column: 1 / 2; grid-row: 2 / 3;}
????.item-b{ grid-column: 5 / 6; grid-row: 2 / 3;}

????我們設(shè)置 .item-b 位與第二行,第五列,但是我們只定義了2行2列,.item-b 的位置并不真實存在,所以,這時隱藏 tracks會以寬度為0的形式產(chǎn)生來填補這個空缺,而 grid-auto-columns 和 grid-auto-rows 就是來指定隱藏 tracks的大小的。比如我們設(shè)定:
????.container{ grid-auto-columns: 60px;},那么上圖將會變?yōu)椋?/p>

grid-auto-flow:
? ? 用來規(guī)定那些沒有指定具體位置的 grid-items 的布局方向。值有:
????row:默認屬性,一行一行的排列,必要時會添加新的行
????column:一列一列的排列,必要時會添加新的列
????dense:如果稍后出現(xiàn)較小的網(wǎng)格項時,嘗試填充網(wǎng)格中較早的空缺


????然后你指定了2個item的確定位置:

????剩下的b , c , d將會這么排布:

????如果將 grid-auto-flow 修改成 column,排布將會發(fā)生如下改變:

兼容性
