CSS Grid 學習筆記 (二)

2023/12/07閱讀時間約 10 分鐘

CSS Grid 學習筆記 (一)當中,我們認識了 grid container 的設定方式,但是除了 container 之外,我們也能控制 grid items。不過在認識控制 grid items 的方法之前,必須先了解到,Grid 系統是用分割線 (grid lines) 來實現切版的。打開 Chrome 的開發者工具,點選 layout 並把 Grid overlays 打開來,畫面就會出現這些輔助線。

Chrome 瀏覽器的 Grid 輔助線

Chrome 瀏覽器的 Grid 輔助線

在上面的範例中,HTML 只保留了一個 div,但是 CSS Grid 卻指定了三欄兩行的排版。我們可以發現,div 並沒有自動佔滿版面,而是乖乖維持自己的那一份空間。換句話說,我們可以讓 div 自由地在 Grid system 移動,而指定的方式,就是透過畫面上的輔助線。


移動 grid items:當個真正的線民 🧵

在上面的開發者工具畫面,我們明確看到每條輔助線都有編號:

  • 行:由左往右,從 1 開始
  • 欄:由上往下,從 1 開始

有了這些編號,我們便可以指定 grid item 從第幾條線擴展到第幾條線,CSS Grid 提供了以下幾種用法,非常淺顯易懂:

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


當然我們也有 shorthand 的簡潔寫法,第一組數值代表行:

.container .itme1 {
grid-column: 1 / 3;
grid-row: 1 / 2;
}


這邊務必留意,1 / 3 並非佔據三分之一欄,而是從第一條輔助線展延到第三條輔助線的意思,所以斜線前面代表起始線,後面則是終止線,不要被分數的表達方式搞混了!

raw-image

起始線不一定要是 1,我們也可以把 div 控制在第二條至第四條線之間。

raw-image

關鍵字 span

利用關鍵字 span,我們就不用人工去算第幾條線了。注意,span 後面所接的數字不是輔助線,而是欄或行的數量。比較常見的作法,是將 span 運在 grid-column-end 或是 grid-row-end 後面,代表最終要擴展多少欄或多少行。

.container .item1 {
  grid-column-start: 1; 
grid-column-end: span 2; 
grid-row: 1 / 2;
}
raw-image

客製命名輔助線

除了使用數字和關鍵字 span 之外,CSS Grid 也提供了客製命名,讓我們給輔助線取名字。 首先在 grid container 透過中括號命名,一個中括號之內可以塞入多個值,也就是為同一條輔助線取多個名字,比方說,底下範例給第二條輔助線取了 col1-end 以及 col2-start 兩個名字。

.container {
grid-template-columns: [col1-start] 1fr [col1-end col2-start] 1fr [col2-end col3-start] 1fr;
grid-template-rows: [row1-start] 1fr [row2-start] 1fr;
}


名字取完後,就可以在 grid items 使用囉:

.container .item1 {
grid-column: col1-start / col2-end;
grid-row: row1-start / row2-start;
}


接著在 Chrome 開發者工具中,Overlay display settings 改為 Show line names,原先的輔助線編碼就會變成客製化名稱。

嗯......這個功能我自己是覺得有點微妙,但也許,我是指也許,在進行 RWD 切版時,可以將某些重要的輔助線取名,以便後續大量重複使用,會比用編碼表達更具易讀性?希望之後實作上能有更多體悟哈哈。


✨ grid-template-areas ✨

grid-template-areas 提供了超級視覺友善的排版方式,讓我們直接在 CSS 裡面,用圖形去定義 grid items 所佔據的空間分布。首先,在 grid container 定義出每個項目所佔據的空間:

.container {
  grid-template-areas:   
"a a c"   
"b b c";
...
}


上面的 a、b、c 代表有三個 grid items,而整張 grid container 則是切割成三欄兩行。至於命名的部分隨意即可,要取名 header、main、aside 等等都沒問題,這邊是參考 MDN 文件的命名方式

接下來只要給對應的 grid items 加上 grid-area,畫面就會依照上方設定切出來囉!☣️注意 grid-area 的值不需要包覆在引號裡面。

.first {
grid-area: a;
}

.second {
grid-area: b;
}

.third {
grid-area: c;
}


在 Chrome 開發者工具開啟 Show area names,即可看見 a、b、c 三個區塊的範圍。這邊順便把輔助線標籤關閉,以求 area names 清楚顯示。

⛑️ grid-template-areas 只能進行矩形的切版,無法實現 L 型之類的不規則切版 ⛑️

grid-template-areas 也可以和 grid-template-rows 以及 grid-template-columns 搭配使用,底下我們結合這三個屬性,實現 navbar、main、sidebar、footer 混合的切版。

.container {
display: grid;
grid-template-columns: 1fr 150px;
grid-template-rows: 100px 1fr 100px;
grid-template-areas:
"navbar navbar"
"main sidebar"
"footer footer";
}

.first {
grid-area: navbar;
}

.second {
grid-area: main;
}

.third {
grid-area: sidebar;
}

.fourth {
grid-area: footer;
}
raw-image

動態 Grid

有的時候,我們無法先知道 Grid 要顯示多少個項目,就像我們永遠不懂主管、老闆或另一半在想什麼。這時候 Dynamic Grids 能幫上忙。透過 grid-auto-flow,我們能指定新加入的 grid item 要填入行或是欄

.container {
grid-auto-flow: row; /* Default setting */
}

grid-auto-flow: row 是預設值,所以在初始狀態,我們添加的 grid item 本來就會以行為基準插入 container。現在把它切換成 column 試試看:

.container {
grid-auto-flow: column;
}


我們會發現 grid-item 改以欄為基準進行排版。

除了指定 row 或是 column 之外,我們還能加入 dense 這個值。dense 代表 grid items 將依序填滿殘存下來的空間,不過這樣有可能會改變項目之間原有的秩序。

"dense" packing algorithm attempts to fill in holes earlier in the grid, if smaller items come up later. This may cause items to appear out-of-order, when doing so would fill in holes left by larger items.

我們將範例中名為 first 的 grid item,設定從第二條輔助線開始擴展,比較好理解上述的說法。

.container {
display: grid;
grid-template: repeat(4, 1fr) / repeat(2, 1fr);
grid-auto-flow: column dense; /* Notice that we added "dense" value */
...
}

.first {
grid-row-start: 2; /* Start the item from the second grid line */
}


因為 grid-atuo-flow 加入了 dense 值,所以第二個 grid item 自動去填滿了 div.first 所殘留的空間,要記得 div.first 現在是從第二條輔助線出發。

這邊也附上沒有加入 dense 的示意圖,請注意因為我們是從第二條輔助線出發,所以上面空出了第一條輔助線到第二條線之間的空間,這便是 densediv.second 所填滿的地方。

raw-image

動態 Grid:自動處理項目的寬度和高度

有時候,當我們完成的 Grid 布局,後續突然有許多莫名其妙的 items 想要加入,但是 grid system 所定義的行與列空間都滿了,該怎麼處置這些不速之客,讓大家都受到公平對待呢?

raw-image
.container {
display: grid;
grid-template: repeat(2, 200px) / repeat(4, 200px);
width: 800px;
}


上方案例中,我們指定了兩行四欄的布局,由於沒有特別設定 grid-auto-flow,所以維持預設的 row。誰知道臨時來了多個重量級的不速之客,結果變成總共四行,導致後面兩行的高度整個被壓縮。

raw-image

這時候,善用 grid-auto-rows 來為不速之客自動設定高度。先給大家 200px 的扣打吧!加入 grid-auto-rows: 200px 之後,大家都受到公平對待了呢~

raw-image




















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