CSS Grid 功能指南

Anderson
12 min readMar 21, 2018

--

以格線的版型基礎,撇除掉傳統使用 float 或絕對定位等方式來設計的思維,另外統一定義,行(Row) 為水平方向, 欄(Column)為垂直方向。

支援版本

可以查閱 can I use 檢查看看各瀏覽器版本支援狀況,到了 2017,各瀏覽器都默默地突然支援了。

和 Flexbox 的差別

兩者部分屬性設定很雷同, flex 雖然大幅改善了 float 的排版方式,但遇到傳統具設計感風格的還是會讓開發者頗為頭痛, Grid 格線系統不只讓語法更為簡單和直覺,可以同時處理二維排版是最大特色。

主要分為 容器 (Container )和項目(Item),容器就泛指最外層的空間,而項目就是指裡面的內容。值得一提的格線系統多了一個單位 fr (fraction的縮寫),代表容器裡面有幾個片段,比起寫死 px 的方式使用起來更為彈性。

容器屬性 (Grid container)

Display

如果要設定格線系統,一定要有該屬性

  • grid:block-level 的格線系統
  • inline-grid:inline-level 的格線系統
// html
<div class="grid-container">
<div class="grid-item item1">1</div>
<div class="grid-item item2">2</div>
<div class="grid-item item3">3</div>
<div class="grid-item item4">4</div>
<div class="grid-item item5">5</div>
<div class="grid-item item6">6</div>
<div class="grid-item item7">7</div>
<div class="grid-item item8">8</div>
<div class="grid-item item9">9</div>
</div>
// css
.grid-container {
display: grid;
grid-template-columns: auto auto auto;
background-color: #FDFDFD;
color: #492645;
padding: 10px;
}
.grid-item {
padding: 30px;
font-size: 24px;
text-align: center;
color: #492645;
}

如果改成 inline-grid 就會變成如下

Grid template

  • grid-template-columns:為排版屬性,定義隔線系統需要多少欄,如果需要三個欄,可以寫成如下,當然也可以給定各欄不同的寬度或自動。如果設定單位都一樣,可以利用 repeat() 含式來替代。
grid-template-columns: auto auto auto;
grid-template-columns: 1fr 1fr 1fr;
grid-template-columns: repeat(3, 1fr);
grid-template-columns: 100px auto 25%;
  • grid-template-rows:意思同上,只是換成設定各行的高度。一樣可以給定各行不同的寬度或自動。
grid-template-rows: 80px 200px 20%;

Grid gap

  • grid-column-gap:各欄間的間隔
.grid-container {
display: grid;
grid-template-columns: auto auto auto;
grid-template-rows: 100px auto 25%;
grid-column-gap: 20px;
background-color: #FDFDFD;
color: #492645;
padding: 10px;
}
  • grid-row-gap:各行間的間隔
.grid-container {
display: grid;
grid-template-columns: auto auto auto;
grid-template-rows: 100px auto 25%;
grid-row-gap: 20px;
background-color: #FDFDFD;
color: #492645;
padding: 10px;
}
  • grid-gap:結合上述兩種縮寫的方式,如下所示
.grid-container {
display: grid;
grid-template-columns: auto auto auto;
grid-template-rows: 100px auto 25%;
grid-gap: 10px 30px;
background-color: #FDFDFD;
color: #492645;
padding: 10px;
}

Justify content

當內容的寬度小於容器的寬度時,且設定寬度的值都用 px 而非百分比時,這屬性 justify-content可以設定容器內的內容對齊方式

  • start:靠左對齊
  • end:靠右對齊
  • center:靠中間對齊
  • stretch:依照比例拉寬到滿版
  • space-around:在各欄間放入多餘的空白,包含開頭和結尾
  • space-between:只在各欄間放入多餘的空白
  • space-evenly:效果同 space-around 但開頭和結尾的空白較多

Align content

跟上述行為類似,該屬性 align-content只是對應目標為行,垂直方向。

  • start:靠左對齊
  • end:靠右對齊
  • center:靠中間對齊
  • stretch:依照比例拉高到滿版
  • space-around:在各行間放入多餘的空白,包含開頭和結尾
  • space-between:只在各行間放入多餘的空白
  • space-evenly:效果同 space-around 但開頭和結尾的空白較多

內層屬性(Grid item)

Grid line

特別的是,起始隔線都是從 1 算起,到第幾條就可以推算區塊的大小和範圍。可以想像把一個容器切成好幾個等分,哪條線到另一條線間就是範圍,可以看以下範例比較清楚。

  • grid-column-start:區塊寬度的起使隔線
  • grid-column-end:區塊寬度的結束隔線
// html
<div class="grid-container">
<div class="grid-item item1">header</div>
<div class="grid-item item2">main</div>
<div class="grid-item item3">empty</div>
<div class="grid-item item4">navigation</div>
<div class="grid-item item5">footer</div>
</div>
// css
.grid-container {
display: grid;
grid-template-columns: 40% auto auto;
grid-template-rows: 100px auto 25%;
grid-gap: 10px 10px;
background-color: #FDFDFD;
color: #492645;
padding: 10px;
}
.grid-item {
padding: 30px;
font-size: 20px;
text-align: center;
color: #492645;
}
.item1 {
background-color: #11CBD7;
grid-column-start: 1;
grid-column-end: 4;

}
.item2 {
background-color: #C6F1E7;
}
.item3 {
background-color: #FAE3E3;
}
.item4 {
background-color: #FA4659;
}
.item5 {
background-color: #FCE4B0;
grid-column-start: 1;
grid-column-end: 4;

}

下面畫面水平方向主要有四條線,header 和 footer 都是從線 1 到線 4 ,main從線 1 到線 2,empty 從線 2到線 3,navigation 從線 3到線 4。

  • grid-row-start:區塊高度的起使隔線
  • grid-row-end:區塊高度的結束隔線
...
.item2 {
background-color: #C6F1E7;
grid-row-start: 2;
grid-row-end: 4;

}
...
.item5 {
background-color: #FCE4B0;
grid-column-start: 2;
grid-column-end: 4;

}

Grid column

可以將上述的寫法縮減,如上面的例子 grid-column-start: 2; grid-column-end: 4; 可以寫成 grid-column: 2 / 4 。另一種作法則是, grid-column: 2 / span 3; 則代表起使點從第二欄開始,向右合併三欄,很像 excel 的合併儲存格。

Grid row

做法同上,方向從水平變為垂直方向,針對對象為行。

Grid area

覺得上面還要寫一堆程式很麻煩,沒關係還有更精簡的寫法,這寫法整合了 grid-row-startgrid-column-endgrid-row-startgrid-row-end 這四個屬性,原本在 css 中要寫四行的現在只要寫一行即可。

.item {
grid-column-start: 1;
grid-column-end: 3;
grid-row-start: 2;
grid-row-end: 4;
}
.item {
grid-area: 2 / 1 / 4 / 3;
}

另一種更酷的做法,直接在 grid-area 中命名對應的名稱,再用 grid-template-areas 使用對應的名稱來展出空間,我們來看下面的例子,利用 grid-area 中設定名稱,再用 grid-template-areas 使用對應的名稱,如果沒有設定特定變數就直接用點 (dot) 即可。如下面 footer 達到置中的效果,就是設定. footer . 前後都放入以點來代替的無名變數。

// html
<div class="grid-container">
<div class="grid-item item1">header</div>
<div class="grid-item item2">main</div>
<div class="grid-item item3">empty</div>
<div class="grid-item item4">navigation</div>
<div class="grid-item item5">footer</div>
</div>
// css
.grid-container {
display: grid;
grid-template-areas: 'header header header' 'main empty navigation' '. footer .';
grid-gap: 10px 20px;
background-color: #FDFDFD;
color: #492645;
padding: 10px;
}
.grid-item {
padding: 30px;
font-size: 20px;
text-align: center;
color: #492645;
}
.item1 {
background-color: #11CBD7;
grid-area: header;
}
.item2 {
background-color: #C6F1E7;
grid-area: main;
}
.item3 {
background-color: #FAE3E3;
grid-area: empty;
}
.item4 {
background-color: #FA4659;
grid-area: navigation;
}
.item5 {
background-color: #FCE4B0;
grid-area: footer;
}

小技巧

如果想要更了解格線系統,可以利用 firefox 提供的開發者工具,點擊 CSS 屬性旁的井字號,或是切換到 Layout 的 分頁,有一些關於格線系統的設定 (詳見下圖)。更多操作請參考 Firefox Devtools

References

  1. CSS Grid Explained in 7 minutes
  2. 格線佈局的基本概念
  3. Introduce To CSS GRID Layout
  4. CSS Tricks

--

--

Anderson

A front-end developer, like the pursuit of beautiful things in life. Hope you like my blog.