CSS Grid 學習筆記 (一)

2023/12/06閱讀時間約 12 分鐘

相較於 Flexbox 著重在單一維度的切版 (row or column),Grid 能讓我們同時照顧兩個維度 (row and column)。CSS Grid 主要由 Grid ContainerGrid Items 所組成,前者是父層容器,後者則是子層項目,概念和 Flexbox 非常相似。

CSS Grid 帶給切版更多彈性,舉個例子,像是英國衛報 (The Guardians) 的網站,就透過 CSS Grid 切出了豐富、複雜的版型。

Grid system 由一組水平線和一組垂直線交錯組合而成,這些相交而成的線被稱為「欄 (column)」和「列 (row)」。
grid system 的示意圖

grid system 的示意圖



Grid Container

要使用 CSS Grid,我們必須先在容器元素呼叫 display: grid。接著便可以透過 grid-template-columns 以及 grid-template-rows 來控制整個版面。

這邊附上原先的 demo 環境程式碼

<div class="container">
<div class="box" style="background-color: #E53935"> ONE</on></div>
<div class="box" style="background-color: #00897B">TWO</div>
<div class="box" style="background-color: #D81B60">THREE</div>
<div class="box" style="background-color: #8E24AA">FOUR</div>
<div class="box" style="background-color: #5E35B1">FIVE</div>
<div class="box" style="background-color: #3949AB">SIX</div>
<div class="box" style="background-color: #1E88E5">SEVEN</div>
<div class="box" style="background-color: #00ACC1">EIGHT</div>
</div>
.container {
height: 700px;
width: 700px;
margin: 200px auto;
background-color: black;
box-shadow: 0 6px 20px rgb(0 0 0 / 0.2);
}

.box {
color: white;
font-size: 1.5rem;
text-align: center;
}
raw-image

在容器元素加上 display: grid 之後,子元素項目的寬度和高度都會占滿整個容器

.container {
display: grid; /* 加入這一行 */
height: 700px;
width: 700px;
margin: 200px auto;
background-color: black;
box-shadow: 0 6px 20px rgb(0 0 0 / 0.2);
}
raw-image

除了 display: grid 之外,還有另一個選擇是 display: inline-grid,效果和 grid 大同小異,差異點在於它會將 container 變成 inline 元素。如果我們想要讓 container 和其他 inline 屬性的元素處在同一行 (例如 <a><span> 等等),就滿適合使用 display: inline-grid


控制行與列:固定大小

前面提過,CSS Grid 有別於 Flexbox 的地方在於二維度排版,而這就有賴於 grid-template-columns 以及 grid-template-rows 了。在 Grid 的世界中,我們仍舊可以使用 50% 這樣的相對單位,但更常見的單位是 fr

fr 代表 fraction,也就是我們要把版面切成多少塊的概念,把真實的寬高計算交給瀏覽器,輕鬆愜意。底下示範把畫面切成 3 欄,寫上 3 個 1fr 即可。中途就算改變 container 的 width 屬性,Grid 照樣會依循 3 等分的原則縮放。

.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr; /* 加入這一行 */
height: 700px;
width: 700px;
margin: 200px auto;
background-color: black;
box-shadow: 0 6px 20px rgb(0 0 0 / 0.2);
}
grid-template-columns: 1fr 1fr 1fr;

grid-template-columns: 1fr 1fr 1fr;

fr 前面的數字不只代表欄數或行數,也象徵著欄、行之間的比例關係。假設我們改成 grid-template-columns: 1fr 2fr 1fr,畫面一樣會被切割為 3 欄,但中間那一欄比其他欄還要寬一倍。

grid-template-columns: 1fr 2fr 1fr

grid-template-columns: 1fr 2fr 1fr

除此之外,fr 可以搭配絕對單位與相對單位一起使用,比方說 grid-template-rows: 150px 1fr 150px,我們將畫面切割成 3 行,第一和最後一行為 150px,而第二行則會占滿剩下的部分。

至於將 grid-template-rows 以及 grid-template-columns 一起使用,則可以讓版面更加豐富。

.container {
display: grid;
grid-template-columns: 1fr 1fr; /* 加入這一行 */
grid-template-rows: 1fr 2fr 1fr 2fr; /* 加入這一行 */
height: 700px;
width: 700px;
margin: 200px auto;
background-color: black;
box-shadow: 0 6px 20px rgb(0 0 0 / 0.2);
}
raw-image

不過每次都要分開寫 grid-template-rows 還有 grid-template-columns 也是挺麻煩的,這時候可以善用 grid shorthand 簡寫:

grid-template: <row-values> / <column-values>

以上面的範例來說,就可以改寫成這樣:

grid-template: 1fr 2fr 1fr 2fr / 1fr 1fr;



控制行與列:範圍值大小

除了將欄與行控制在固定大小之外,我們也能透過 minmax() 來 Grid 大小的範圍值。裡面需要帶入兩個參數,前面放最小值,半形逗號隔開後面加上最大值。

grid-template: minmax(<min value>, <max value>)

假設我們使用 grid-template-columns: minmax(400px, 600px),當畫面寬度超過 600px,Grid items 將佔不滿整個 container。

raw-image

相對來說,當畫面小於 400px 就會被切掉,出現滾輪。

raw-image

如果某一欄的內容很長的話,將最大值設為 auto 也是不錯的選擇,這樣就不會出現內容溢出的窘況了。

minmax(<min value, auto>)



控制行與列:懶人重複法 repeat()

每次都要慢慢手打單位是件很麻煩的事情,假設有 8 個 1fr,光想像頭就開始痛了。這時候善用 repeat(),對手腕和心靈健康都很有幫助。

grid-template: repeat(<repeat times>, <unit values>)

要切出同等份的 8 欄,可以這樣寫:

grid-template-columns: repeat(8, 1fr);


搭配剛剛提到的 mimmax() 也完全沒問題:

grid-template-columns: repeat(4, minmax(300px, auto));



控制行與列:以內容大小為主 fit-content()

若希望 grid items 可以隨著內容縮放,不妨用用看看 fit-content()裡面只需要帶入一個參數:最大值。若帶入 300 px,就代表 grid items 會隨著內容擴張,直到 300px 為止。

.container {
display: grid;
grid-template-columns: repeat(3, fit-content(300px));
height: 700px;
width: 700px;
margin: 200px auto;
background-color: black;
box-shadow: 0 6px 20px rgb(0 0 0 / 0.2);
}


在上方的例子中,我們將畫面切割成 3 欄,並規定每一欄都隨其內容擴張,直到觸及最大值 300px 為止。

raw-image

添加行或欄之間的空隙 gap()

Flexbox 提供了 gap() 讓我們輕鬆控制 flex items 之間的空隙,Grid 也有提供。我們可以用 row-gap 或是 column-gap 來指定要控制行或是列的空隙大小。

.container {
display: grid;
grid-template: 1fr 1fr / repeat(4, 1fr);
column-gap: 20px; /* watch me baby! */
row-gap: 30px; /* watch me baby! */
height: 700px;
width: 700px;
margin: 200px auto;
background-color: black;
box-shadow: 0 6px 20px rgb(0 0 0 / 0.2);
}
raw-image

覺得分成兩行寫太麻煩的話,也可以參考 grid-gap 的 shorthand 寫法,如果只帶入一組設定值,那 row gap 和 column gap 都會套用。帶入兩組設定值的話,前面是 row gap,後面是 column gap。

.container {
...
grid-gap: 20px /* Both row-gap and column-gap are 20px */
grid-gap: 20px 30px /* Row gap equals to 20px while column gap is 30px */
}







16會員
34內容數
Bonjour à tous,我本身是法文系畢業,這邊會刊登純文組學習網頁開發的筆記。如果能鼓勵更多文組夥伴一起學習,那就太開心了~
留言0
查看全部
發表第一個留言支持創作者!