CSS 語法 15:格線 grid, 單位 fr

格線 grid

格線會用到幾個屬性來定義,row (列) 指的是水平方向的,column (欄) 指的是垂直方向。
給定大小的值可以用 px (pixel),或是用 fr ,1 fr 就是指一個格線單位。
直接舉例,不然根本不知道在說什麼:

.boxes {
display: grid;
border:1px solid black;
}
<div class="boxes">
 <div>1</div>
 <div>2</div>
 <div>3</div>
 <div>4</div>
 <div>5</div>
</div>
1
2
3
4
5

目前我們沒有宣告 row(列) 或 column(欄) 的值,所以看起來就是呆呆的排下來,沒有什麼特別。

我們可以用 grid-template-columns 來宣告欄的數量和寬度;用 grid-template-rows 來宣告列的數量和寬度。

.boxes {
display: grid;
grid-template-columns: 100px 100px 100px; /*宣告有三欄,每一欄是 100px*/
}
<div class="boxes">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</div>
1
2
3
4
5

現在我們有宣告3個欄位和寬度,裡面的元素就會依序排下來,橫的每三格就換一行。

fr 單位

上面的例子,我們發現這三欄根本沒有把整個寬度撐滿,右邊還留下一些空間。
這時候我們可以用 fr 這個單位。

.boxes {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
<div class="boxes">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</div>
1
2
3
4
5

這次我們可以看到整個寬度剛好分配給3個格線了。

上面的例子我們可以寫得更精簡:

.boxes {
display: grid;
grid-template-columns: repeat(3, 1fr); /* 重複3次1fr */
}

用 repeat(3, 1fr) 來表示重複3次1fr 這樣和寫 1fr 1fr 1fr 結果會是一樣的。

.boxes {
display: grid;
grid-template-columns: 90px repeat(5, 1fr) 90px;
}
1(90px)
2
3
4
5
6
7(90px)
8
9
10
.boxes {
display: grid;
grid-template-columns: 2fr 1fr 1fr;
}
1
2
3
4
5
.wrapper {
display: grid;
grid-template-columns: repeat(3, 1fr 2fr); /*重複3次 1fr,2fr 這樣交錯出現*/
}
1
2
3
4
5
6
7
8
9
10
.boxes{
display: grid;
grid-template-columns: repeat(6, 1fr);
grid-auto-rows: 100px;/* 設定高度為100PX*/
}
1
2
3
4
5
6
7
8
9
10

在上面這個例子,我們設定了高度為100px

.boxes {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: minmax(80px, auto); /*設定最小高度為 80px,最大高度則自動依內容而定*/
}
1
2
3
換行
換行
換行
換行
換行
這一格因為內容而把格子撐高了
4
5
6
7
8
9
10

合併宣告

▼grid-template-columns 和 grid-template-rows 可以一起用 grid-template 宣告。

grid-template-rows: 60% 1fr;
grid-template-columns: 200px 1fr;

▼以上可以合併為

grid-template: grid-template:60% 1fr/ 200px 1fr;

 

Grid Lines

當我們要顯示的元素是跨越格線的,要宣告的方式是以格線的「線」為宣告基準,格線的順序編號如下:

如上圖,我們要先宣告格線:

.boxgride {
display: grid;
grid-template-columns: repeat(3, 1fr);
}

A盒子的宣告如下:

.boxA {
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 1;
grid-row-end: 2;
}

B盒子的宣告如下:

.boxB {
grid-column-start: 2;
grid-column-end: 3;
grid-row-start: 1;
grid-row-end: 2;
}

而D盒子有跨越2個 columns

.boxD {
grid-column-start: 1;
grid-column-end: 3;
grid-row-start: 2;
grid-row-end: 3;
}

grid-column-gap, grid-row-gap

如果想讓每個盒子之間空出一點空間,就加上 grid-column-gap 和 grid-row-gap 屬性,如下:

.boxgride {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-column-gap: 15px;
grid-row-gap: 5px;
}
A
B
C
D
E

巢狀格線

每一個格子裡面都還可以放置格子

<div class="boxgride"> 
 <div class="boxA">
   <div class="yellowbox"></div>
   <div class="yellowbox"></div>
   <div class="yellowbox">
     <div class="pinkbox"></div>
   </div>
 <div class="boxB">B</div>
 <div class="boxC">C</div>
 <div class="boxD">D</div>
 <div class="boxD">E</div>
</div>
B
C
D
E

z-index 重疊

格子的宣告是可以互相重疊的,用 z-index 屬性來控制誰前誰後,如下範例:

.boxgride {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-auto-rows: 100px;
width:300px;
}

.boxA {
grid-column-start: 1;
grid-column-end: 3;
grid-row-start: 1;
grid-row-end: 3;
z-index:2;
background-color:#77cfe6;
opacity:0.8;
}

.boxB {
grid-column-start: 2;
grid-column-end: 4;
grid-row-start: 2;
grid-row-end: 4;
z-index:1;
background-color:#ff9ecb;
}
A
z-index:2;
B
z-index:1;

 

合併宣告

▼如果想宣告

grid-column-start:2;
grid-column-end:5;

▼可以合併寫為

grid-column:2/5;

▼row的宣告也可以用一樣的原理

grid-row:3/6;

▼我們甚至可以用 grid-area 合併上面的兩段

grid-area:3/2/6/5;

▲grid-area 的值順序為 grid-row-start / grid-column-start / grid-row-end / grid-column-end

 

排序

grid 的排序沒有特別設定時,預設值是橫向排列(row),我們可以把它改成縱向排列

grid-auto-flow: column;

我們也可以針對個別<div>設定它的順序位置,比如我們要把這個 grid 裡面的第2個<div>一到最後面。

.box div:nth-child(2){
order:1;
}

因為沒有設定時順序都是0,所以現在只有第二個<div>設定為1,就會跑到最後一個。

延伸閱讀:CSS 遊戲,邊玩邊學,包含 flex 和 grid 的遊戲