CSS 中的 Grid 佈局 徹底指南

Grid 是一個基於二維網格佈局的系統,有了它咱們能夠很是方便的實現過去很複雜佈局,無需再使用float, inline-block, position 這些本質上是 hack 的方法。css

CSS網格佈局擅長於將一個頁面劃分爲幾個主要區域,以及定義這些區域的大小、位置、層次等關係(前提是HTML生成了這些區域)。算法

它像表格同樣,網格佈局讓咱們可以按行或列來對齊元素。 然而在佈局上,網格比表格更可能作到或更簡單。瀏覽器

網格佈局概念

在學習以前須要瞭解如下網格的幾個概念。網絡

網格軌道(Grid Tracks)

網格軌道 是兩條網格線之間的空間。它們經過使用屬性grid-template-columnsgrid-template-rows在網格中定義。函數

上圖中有兩行三列,一行或一列就叫作軌道。佈局

網格線(Grid Lines)

使用Grid佈局在顯式網格中定義軌道的同時會建立網格線。學習

網格線能夠用它們的編號來尋址。在從左到右的語言中,列線1將位於網格的左側,行線1將位於其頂部。線編號遵循文檔的寫入模式,所以在從右到左的語言中,列線1行將位於網格的右側。下面的圖片展現了該網格的線編號,假設語言是從左到右的。flex

網絡單元格(Grid Cell)

Grid佈局中,網絡單元格是 CSS 網格中的最小單元。它是四條網格線之間的空間,很是像表格單元格。ui

網格區域(Grid Areas)

網格區域是網格中由一個或者多個網格單元格組成的一個矩形區域。本質上,網格區域必定是矩形的。例如,不可能建立T形或L形的網格區域。spa

網格間距(Gutters)

網格間距是網格軌道之間的間距,能夠經過grid-column-gapgrid-row-gap在Grid佈局中建立。

使用 Grid 佈局

和 flex 相似,要使用網格佈局,首先要有一個容器,將一個元素的display設置爲grid就能夠獲得一個 grid 容器。容器的子項就是網格項(grid items),它有點相似table中的td,可是更加靈活。

float, clear, 和 vertical-align 元素對網格容器不起做用。

容器上的屬性

網格模板

建立了網格容器,咱們就能夠定義這個網格有多少行有多少列,而且每一行每一列的大小。

grid-template-rows

咱們使用grid-template-rows來顯性定義網格有多少行。它能夠取以下的值:

  1. none 關鍵字,表示不明確的網格。全部的行和其大小都將由grid-auto-rows 屬性隱式的指定。
  2. 非負值的長度大小:如px, em, vw
  3. 百分比:相對於網格容器的,若是是inline-grid,則百分比值將被視爲auto
  4. flex:非負值,用單位fr來定義網格軌道大小的彈性係數。每一個定義了flex 的網格軌道會按比例分配剩餘的可用空間
  5. max-content關鍵字,表示以網格項的最大的內容來佔據網格軌道的
  6. min-content關鍵字,表示以網格項的最大的最小內容來佔據網格軌道
  7. auto若是該網格軌道爲最大時,等同於max-content,爲最小時,等同於 min-content

grid-template-columns

它和grid-template-rows相似,一個設置網格行,一個是設置網格列。

.container {
    display: grid;
    grid-template-columns: 40px 50px auto 50px 40px;
    grid-template-rows: 25% 100px auto;
}
複製代碼

.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 100px 100px;
}
複製代碼

Grid 中可使用的函數

在 Grid 佈局中咱們還可使用以下 3 個函數

repeat()

repeat函數能夠以一種更簡潔的方式去表示大量並且重複行的表達式。

好比上面grid-template-columns: 1fr 1fr 1fr;咱們能夠寫成repeat(3, 1fr)。它的第一個參數是重複的次數,而能夠爲auto-fillauto-fit

auto-fill

若是容器有明確的大小或最大大小,則重複次數是最大可能的正整數,不會致使網格溢出其網格容器。若是任何重複次數都會溢出,則重複次數爲1。

auto-fit

auto-fill的行爲相同,只是在放置網格項後,任何空的重複軌道都會摺疊。

#container {
  display: grid;
  grid-template-columns: repeat(2, 50px 1fr) 100px;
  grid-gap: 5px;
  box-sizing: border-box;
  height: 200px;
  width: 100%;
  background-color: #8cffa0;
  padding: 10px;
}

#container > div {
  background-color: #8ca0ff;
  padding: 5px;
}
複製代碼

minmax()

定義了一個長寬範圍的閉區間。它接受兩個參數,最小值 和 最大值。它返回這個區間中的值。

minmax(max-content, 300px),最大不能大於300px

minmax(200px, 1fr) 最小不能小於200px

fit-content()

它至關於min(maximum size, max(minimum size, argument))。參數能夠是長度值和百分比。

它在內容的最小值和參數中去一個最大值,而後再在內容的最大值中取一個最小值。

也就是當內容少時,它取內容的長度,若是內容多,內容長度大於參數長度時,它取參數長度。

grid-template-areas

這個屬性網格區塊,須要和grid-area配合使用,它的值能夠是none字符串

爲字符串時每個給定的字符串會生成一行,一個字符串中用空格分隔的每個單元(cell)會生成一列。多個同名的,跨越相鄰行或列的單元稱爲網格區塊(grid area)。非矩形的網格區塊是無效的。

#page {
  display: grid;
  width: 100%;
  height: 250px;
  grid-template-areas: "head head"
                       "nav main"
                       "nav foot";
  grid-template-rows: 50px 1fr 30px;
  grid-template-columns: 150px 1fr;
}

#page > header {
  grid-area: head;
  background-color: #8ca0ff;
}

#page > nav {
  grid-area: nav;
  background-color: #ffa08c;
}

#page > main {
  grid-area: main;
  background-color: #ffff64;
}

#page > footer {
  grid-area: foot;
  background-color: #8cffa0;
}
複製代碼

grid-template-areas字符串,關聯 grid item 的grid-area,用它定義一片區域。

grid-template

grid-template-rowsgrid-template-columnsgrid-template-areas的簡寫。

它的值能夠分三種狀況:

  1. none
  2. 只有定義行和列時可使用rows/columns語法,如grid-template: 100px 1fr / 50px 1fr;
  3. 當三個都有時,也用一個/分隔,並且它的右邊也仍是columns,可是它的左邊語法是<line-names>? <string> <track-size>? <line-names>?
.page {
    grid-template: [header-top] "a a a"     [header-bottom]
                   [main-top]   "b b b" 1fr [main-bottom]
                   / auto 1fr auto;
}
/* line-names 是可選的,自定義名稱,須要使用中括號包裹,它其實至關於註釋 string 網格項 grid-area 的關聯值 track-size 這一行的大小 */
複製代碼
#page {
  display: grid;
  width: 100%;
  height: 200px;
  grid-template: [header-left] "head head" 30px [header-right]
                 [main-left]   "nav main" 1fr  [main-right]
                 [footer-left] "nav foot" 30px [footer-right]
                 / 120px 1fr;
}

header {
  background-color: lime;
  grid-area: head;
}

nav {
  background-color: lightblue;
  grid-area: nav;
}

main {
  background-color: yellow;
  grid-area: main;
}

footer {
  background-color: red;
  grid-column: foot;
}
複製代碼

grid-row-gap / row-gap

用來設置行元素之間的間隙(gutter) 大小。它的值能夠是長度值、百分比和normal

CSS Grid Layout 起初是用 grid-row-gap 屬性來定義的,目前逐漸被 row-gap 替代。可是,爲了兼容那些不支持 row-gap 屬性的瀏覽器,你須要使用帶有前綴的屬性。

.box{
    grid-row-gap: 1em;
}
複製代碼

grid-column-gap / column-gap

用來設置元素列之間的間隔 (gutter) 大小。它的值能夠是長度值、百分比和normal

normal 在 多列布局 時默認間隔爲1em,其餘類型佈局默認間隔爲 0。

grid-row-gap同樣,它漸漸被column-gap取代。

.page {
    grid-column-gap: 1em;
}
複製代碼

grid-gap / gap

是上面兩個屬性的簡寫,語法是row-gap column-gap。若是沒有column-gap那麼它將被設置成跟row-gap同樣的的值。

它也漸漸被gap取代。

#grid {
  display: grid;
  height: 200px;
  grid-template: repeat(3, 1fr) / repeat(3, 1fr);
  gap: 20px 5px;
}

#grid > div {
  background-color: lime;
}
複製代碼

隱式建立的行和列

css gird 會根據周圍項目的大小和跨度自動調整網格上每一個項目的位置。

好比:

.box {
  display: grid;
  grid-template: 25px / 100px 160px;
  background: #000;
}
.box * {
  background: #ccc;
}
.box *:nth-child(even) {
  background: #777;
}
複製代碼

咱們只定義了一行,兩列。可是咱們卻有 5 個子元素。CSS網格決定將它們擴展到隱式建立的空間,新建的隱式行中的列自動從先前指定的grid-template-rows屬性繼承行高。

grid-column-start, grid-column-end, grid-row-startgrid-row-end這 4 個屬性是 grid item 上的,它能夠定義一個 grid item 的位置,若是咱們將它的位置設置的超出咱們定義的網格,那時也會隱式建立行或列。

grid-auto-rows

指定了隱式建立行的大小。它的值能夠是:

  1. 長度值px em vmax
  2. 百分比:相對於網格容器
  3. flex:非負值,用單位fr來定義網格軌道大小的彈性係數。每一個定義了flex 的網格軌道會按比例分配剩餘的可用空間
  4. max-content關鍵字,表示以網格項的最大的內容來佔據網格軌道的
  5. min-content關鍵字,表示以網格項的最大的最小內容來佔據網格軌道
  6. auto若是該網格軌道爲最大時,等同於max-content,爲最小時,等同於 min-content

它的值和grid-template-rows是同樣的。

.box {
  display: grid;
  grid-template: 25px / 100px 160px;
  gap: 10px 20px;
  grid-auto-rows: 50px;
  background: #000;
}
.box * {
  background: #ccc;
}
.box *:nth-child(even) {
  background: #777;
}
複製代碼

grid-auto-columns

指定了隱式建立的網格的列寬。它的取值和grid-auto-rows同樣。

#grid {
  height: 100px;
  display: grid;
  grid-template-areas: "a a";
  grid-gap: 10px;
  grid-auto-columns: 200px;
}

#grid > div {
  background-color: lime;
}
複製代碼

grid-auto-flow

控制着自動佈局算法怎樣運做,精確指定在網格中被自動佈局的元素怎樣排列。

若是咱們在一個div中寫幾個div,再對父級設置display: grid;,從視覺的角度能夠發現沒什麼變化。可是若是咱們再將父級div加上一句grid-auto-flow: column;咱們就發現如今子元素在一行顯示,和彈性盒子效果差很少。

grid-auto-flow的值以下:

  1. row指定自動佈局算法按照經過逐行填充來排列元素,在必要時增長新行。(默認值)
  2. column指定自動佈局算法經過逐列填充來排列元素,在必要時增長新列。

在這兩個關鍵字後面還能夠加上dense關鍵字。語法是[ row | column ] || dense

該關鍵字指定自動佈局算法使用一種「稠密」堆積算法,若是後面出現了稍小的元素,則會試圖去填充網格中前面留下的空白。這樣作會填上稍大元素留下的空白,但同時也可能致使原來出現的次序被打亂。

若是省略它,使用一種「稀疏」算法,在網格中佈局元素時,佈局算法只會「向前」移動,永遠不會倒回去填補空白。這保證了全部自動佈局元素「按照次序」出現,即便可能會留下被後面元素填充的空白。

grid-auto-flow: row;

grid-auto-flow: row dense;

grid

grid是 CSS 簡寫屬性,它幾乎包括上面提到的全部屬性(除了gap)。

與其餘簡寫屬性一樣,如有次級屬性未被聲明,其將使用初始值。另外,儘管此簡寫聲明沒法設置網格的槽(gutter),槽會被該聲明重置。

它的值能夠分爲 3 類

grid-template

就和grid-template簡寫同樣,如grid: [linename1] "a" 100px [linename2];

grid-template-rows / [ auto-flow && dense? ] grid-auto-columns?

grid-template-rows設置行高(grid-template-columns被設置爲none),/ 後面的auto-flow必需要寫(grid-auto-flow被設置爲 column),最後grid-auto-columns置明確該如何自動重複列軌道(grid-auto-rows屬性設爲auto)。

grid: repeat(3, [line1 line2 line3] 200px) / auto-flow 300px;

[ auto-flow && dense? ] grid-auto-rows? / grid-template-columns

這種寫法和上種寫法相反,這種是設置grid-template-columnsrows屬性爲none)。可選的設置grid-auto-rows屬性(columnsauto

grid: auto-flow dense / 30%;

網格項上的屬性

grid-row-start, grid-row-end, grid-column-start, grid-column-end

分別指定 grid item 在網格中的行起始位,行結束位,列起始位,列結束位。

這就須要瞭解以前介紹的網格線概念,橫線(row)從上到下遞增,豎線(column)從作到右遞增,都是從 1 開始算。

它們能夠取以下值:

  1. auto表示自動放置,自動跨度或默認span爲 1
  2. 數字表示網格線
  3. span 數字表示跨越幾個格子,數字小於等於0無效。若是超過網格大小會隱式建立行或列。

它和table有點類似

若是設置的位置超出指定大小,會獲得不穩定的效果,應該避免這種狀況。

.box {
  display: grid;
  grid: 100px 100px / 100px 100px;
  background: #000;
}
.box * {
  background: #ccc;
}
.box *:nth-child(even) {
  background: #777;
}
.box1 {
  grid-column-start: span 5;
}
複製代碼

grid-row, grid-column

grid-rowgrid-column分別是上面 4 個屬性簡寫。

它們值的語法是start / end。若是隻有一個值那麼它是startend值爲默認auto

當列數未知時,可使用-1讓它一直擴展到網格末尾。

使用負值

grid-area

上面咱們已經展現了grid-areagrid-template-areas結合的用法。grid-area實際上是grid-row-startgrid-column-startgrid-row-endgrid-column-end的簡寫。

它的默認值是grid-area: auto;

若是設置了 4 個值的話那麼它的順序是

grid-area: row-start / column-start / row-end / column-end;

若是設置了 3 個值,那麼最後一個爲auto

若是設置了 2 個值,那麼後兩個爲auto

若是設置了 1 個值,那麼後三個爲auto

若是第一項是自定義表示,那麼被忽略的都爲自定義表示

.box1 {
  grid-area: a / a;
}

/* 至關於 */

.box1 {
    grid-row-start: a;
    grid-column-start: a;
    grid-row-end: a;
    grid-column-end: a;
}
複製代碼

網格項的內容對齊

咱們可使用align-selfjustify-self調整 grid item 的內容對齊方式。

align-self用來垂直方向對齊,justify-self用來水平方向對齊。

align-self

flex 佈局也可使用這個屬性。它經常使用以下 3 個值:

  1. start: 內容頂端對齊
  2. center: 內容垂直居中
  3. end: 內容底部對齊

justify-self

它經常使用以下 3 個值:

  1. start / left: 內容左對齊
  2. cneter: 內容水平居中
  3. end / right: 內容右對齊

相關文章
相關標籤/搜索