iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 6
1
自我挑戰組

30 天 CSS 隨手筆記系列 第 6

30 天 CSS 隨手筆記 - 第 06 天 - OMG... Grid Layout~!! ( 2/7 - 概觀 )

本來預計今天要筆記 Grid 相關屬性的,但考慮過後決定延到下一篇。

這篇分為三個部分:

  1. ( 舉例 ) grid 大概是什麼樣子呢?
  2. 術語介紹
  3. DEMO - 範例說明

想說可以先有個概觀,之後細講各個屬性時會更有感。

本來的規劃其實是:

  1. 術語介紹
  2. 舉例說明

但感覺一開始就講術語的話,感覺太抽象又太不有趣了~ 所以最後調整了順序。

這個範例是來自 CSS Tricks 的一篇文章: A Complete Guide to Grid ,是在解釋其中一個 CSS 屬性時的舉例。我覺得這個例子是 結構與樣式分離 的一個很好的實現,因此決定以此作為開頭 =D


grid 大概是什麼樣子呢?

目標

  1. 切出一個有 頁首主要區塊右側側欄頁尾 的頁面
  2. 主要區塊右側側欄 並排,寬度為 2:1,且兩者之間有 20px 的空格
1 單位 1 單位 20px 1 單位
頁首 頁首 頁首 頁首
主要區塊 主要區塊 側欄
頁尾 頁尾 頁尾 頁尾

如果使用其他 layout 的話,我的 html 可能會寫成這樣:

<body>
    <header class="header" />
    <div>
        <main class="main" />
        <aside class="sidebar" />
    </div>
    <footer class="footer" />
</body>

( css:略 )

而使用 grid 時,則可以這樣寫:

html

<body class="container">
    <header class="header" />
    <main class="main" />
    <aside class="sidebar" />
    <footer class="footer" />
</body>

css

.header  { grid-area: header; }
.main    { grid-area: main; }
.sidebar { grid-area: sidebar; }
.footer  { grid-area: footer; }

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

然後就完成了~!! ( 最後結果:https://jsfiddle.net/lazy_shyu/axu2at32/3/ )

grid example clap

grid-template-areas 屬性裡面,簡直就是把我們想要的版面寫出來啊!
有一種 "只要會使用 excel 的合併儲存格,就可以理解 grid system" 的感覺 XDD


術語介紹

以下參考 A Complete Guide to Grid :: CSS Tricks ,來定義幾個常用的 grid 術語。

  1. Grid Container

    設定為 display: grid / display: inline-grid / display: subgrid 的元素。

  2. Grid Item

    grid container 的下一層元素 ( direct descendants )。

  3. Grid Line

    有水平 / 垂直兩種,就是從頭畫到底的一條隔線

    範例:column grid line

  4. Grid Track

    兩條相鄰的 grid line 所圍出的範圍,也就是 一列一欄

    範例:一列

  5. Grid Cell

    兩條相鄰的 column grid line 與兩條相鄰的 row grid line 所圍出的範圍,
    可以看成是 excel 裡面的一個儲存格。

  6. Grid Area

    兩條 column grid line 與兩條 row grid line 所圍出的範圍,可能是多個 grid cell 的組合。

說術語好像太深奧了,其實只是統一幾個名詞的講法,讓之後的敘述更方便而已 XD


DEMO - 範例說明

以下會一邊解說,一邊說明第一個範例中所設定的樣式。

  1. step 1 - 寫好 html 結構

    首先,我們先寫好四個主要元素 - header / main / aside / footer

    <body>
        <header class="header" />
        <main class="main" />
        <aside class="sidebar" />
        <footer class="footer" />
    </body>
    

    現在是 no-layout layout:

    http://ithelp.ithome.com.tw/upload/images/20161221/20103812FyqX8MruSG.png

  2. step 2 - 給個區塊一些樣式

    這個步驟與 grid 完全沒有關係,只是為了更方便識別各個區塊而已 XD
    加上樣式後,比較方便識別個個區塊了:

    http://ithelp.ithome.com.tw/upload/images/20161221/20103812hXQYYectzx.png

  3. step 3 - 將 body 設為 grid container

    body {
        display: grid;
    }
    

    畫面上看起來沒有變化,但這個設定就可以讓 body 的下一層元素知道 "噢,我是 grid item,接著可能要處理一些複雜的 layout 了"

  4. step 4 - 定義欄寬

    根據之前 "main 跟 sidbar 並排,寬度為 2:1,且兩者之間有 20px 的空格" 的規則,
    寬度應該是:

    1. main - 2 * (100% - 20px) / 3
    2. sidebar - (100% - 20px) / 3

    但 grid 裡面有個聰明的 fr 單位,可以自己幫我們計算剩餘空間的比例,因此我們可以這樣設定:

    body {
        display: grid;
    
        /* 
         * 第一欄 2fr、第二欄 20px、第三欄 1fr
         * 在這個例子中,grid 會先把總寬度減去 20px 再把剩下的空間依照 2:1 的比例分給第ㄧ、第三欄。
         */
        grid-template-columns: 2fr 20px 1fr;
    }
    

    因為預設是一個 grid item 佔一個 area 的空間,所以這時候會看到版面變得怪怪的,
    但莫急莫驚慌,我們馬上就能修正。

    http://ithelp.ithome.com.tw/upload/images/20161221/20103812fLVJZlsF11.png

  5. step 5 - 定義 grid area

    body {
        display: grid;
        grid-template-columns: 2fr 20px 1fr;
    
        /* 
         * 兩條直的 grid line、兩條橫的 grid line 包以來的範圍,可以定義成一個 grid area
         * ( 其中 main 跟 sidebar 之間的 "." 是留空的意思 )
         */
        grid-template-areas: "header header header "    /* 第一列 */
                             "main   .      sidebar"    /* 第二列 */
                             "footer footer footer ";   /* 第三列 */
    }
    
  6. step 6 - 定義 grid item 要參照的 grid area

    剛剛定義好了在 grid 系統中各個 area 的位置,
    現在則要告訴各個 grid items,你應該要去參照哪個位置。

    在這個例子中是這樣設定的。

    .header  { grid-area: header; }
    .main    { grid-area: main; }
    .sidebar { grid-area: sidebar; }
    .footer  { grid-area: footer; }
    

    然後就能看到我們想要的樣式了~!!

    http://ithelp.ithome.com.tw/upload/images/20161221/20103812ne1lIWwdLp.png

  7. step 7 - 定義列高

    ( 這個步驟其實可以略過 XD )
    目前沒有內容可以把 grid item 撐開,但我想要中間的 row 高一點。

    所以我可以這樣設定:

    body {
        display: grid;
        grid-template-columns: 2fr 20px 1fr;
        grid-template-areas: "header header header "
                             "main   .      sidebar"
                             "footer footer footer ";
    
        /* 設定個列的高度 */
        grid-template-rows: 100px 200px 100px;
    }
    

    最後就能得到這樣的結果 (,, ・∀・)ノ゛

    http://ithelp.ithome.com.tw/upload/images/20161221/20103812sn4AYvSvpN.png


我覺得這樣其實已經很厲害了,有一種回不去的感覺啊!
明天會開始逐一筆記其他的相關的 grid 屬性,並且各自寫個 DEMO 練習 ( 理想上 )。


上一篇
30 天 CSS 隨手筆記 - 第 05 天 - OMG... Grid Layout~!! ( 1/7 - 簡介 )
下一篇
30 天 CSS 隨手筆記 - 第 07 天 - OMG... Grid Layout~!! ( 3/7 - container 屬性 1 )
系列文
30 天 CSS 隨手筆記30

1 則留言

0
RocMark
iT邦新手 5 級 ‧ 2017-01-02 06:39:57

好神...
正在為了畢專而自學網頁設計。(學生QAQ)
好希望快點能用Grid阿QAQ

期待明年三月~!!
不過到時候也不是全部都支援啦,暫時還需要配合 feature query 使用 O艸Q

我要留言

立即登入留言