---
# System prepended metadata

title: 0331 RWD
tags: [HTML / CSS]

---

# 0331 RWD
###### tags: `HTML / CSS`

## 格線系統

* 網頁中常用欄數： 1, 2, 3, 4
* 格線系統可先將畫面分割成多個欄，之後就可以直接套用
  * 1, 2, 3, 4 取最小公倍數 = 12，所以先將畫面分割成 12 欄
* 格線系統沒有分間距，所以會使用 padding 加上 box-sizing 做間距

col-1
col-2
col-3
col-4
...到 col-12

全部分成 12 份
- 在設定時只要 col 後面數字加起來等於 12 即可，可以混搭 6-6、4-3-5、8-1-2-1.... 等
- 通常習慣使用 container 跟 col (column) <後面還有 [row](https://hackmd.io/6gZ8OsD2T96LkrsCLrU8Kg?both#%E5%B7%A2%E7%8B%80%E7%B5%90%E6%A7%8B)> 做容器命名
- 製作兩欄版面時：
  - 用 50% 50% 分割畫面
  - 用 border-box 跟 padding 處理尺寸計算及物件間距需求
  - 外面再包一個 Flex 容器處理物件橫排
  - 亦可調整是否滿版或設定最大寬度並置中 (例：`max-width: 1200px; margin: auto;`)

![圖解格線系統2](https://i.imgur.com/oNiN71I.png)

- 主要容器：
  - 格線容器（container 及 col <後面還有 row>）
    - 純分割用，處理欄數、版面比例及大小 （例：col-12 = 橫向 12 欄，欄寬 8.333333%）
  - 內容容器：專門放內容及調整單一群組物件版面
- 在 CSS 中小數點取到後六位數比較精準，所以比例上都使用到小數第六位
```html=
<style>
  .container {
    display: flex;
    flex-wrap: wrap;
  }
  
  [class*="col-"] {  /* 使用屬性選取器減少重複設定 */
    padding: 0 15px;
    box-sizing: border-box;
  }
  
  .col-1 { width: 8.333333% ;} /* 分到 1/12 */
  .col-2 { width: 16.666666%;} /* 分到 2/12 */
  .col-3 { width: 25%;} /* 以此類推 */
  .col-4 { width: 33.333333%;}
  .col-5 { width: 41.666666%;}
  .col-6 { width: 50%;}
  .col-7 { width: 58.333333%;}
  .col-8 { width: 66.666666%;}
  .col-9 { width: 75%;}
  .col-10 { width: 83.333333%;}
  .col-11 { width: 91.666666%;}
  .col-12 { width: 100% }
</style>

<body>  
  <div class="container">
    <div class="col-7"><img src="https://fakeimg.pl/300x200/#eee"></div>
    <div class="col-2"><img src="https://fakeimg.pl/300x200/#eee"></div>
    <div class="col-3"><img src="https://fakeimg.pl/300x200/#eee"></div>
    <!--- 版面以 7/12, 2/12, 3/12 這三種尺寸分割 --->
    <!--- 每一個 container 內的 col 數字加起來要等於 12 --->
  </div>
</body>
```


### 搭配 RWD 之命名規則
裝置 | 增加 class 代碼 | min-width (最小欄寬)
----|:----:|:---------:
手機(直、橫） | 無 | 無
平板(直)|md (medium 中)| 768px
平板(橫)|lg (large 大)| 992px
桌機|xl (extra-large 特大)| 1200px

* 範例：
```css= 
@media screen and (min-width: 768px) {
  .col-md-1 {width: 8.333333%;}
  .col-md-2 {width: 16.666666%;}
  .col-md-3 {width: 25%;}
  .col-md-4 {width: 33.333333%;}
  .col-md-5 {width: 41.666666%;}
  .col-md-6 {width: 50%;}
  .col-md-7 {width: 58.333333%;}
  .col-md-8 {width: 66.666666%;}
  .col-md-9 {width: 75%;}
  .col-md-10 {width: 83.333333%;}
  .col-md-11 {width: 91.666666%;}
  .col-md-12 {width: 100%;}
}

其他版面修改 min-width 還有將 .col-md- 換成 .col-lg- / .col-xl- 即可
```

* 編寫多層結構 code 時，注意：
  * 結構錯誤，貼到別的 code 裡面或是括號遺漏
  * 拼音錯誤，複製貼上好幫手
  * 空白與否
  * 有錯誤時使用開發者工具看看 css 有無運作

### 巢狀結構
- 指有多層欄在同一個高度，需套用特殊版型格線
- 為配合巢狀結構，在範本中多加一層 row 來輔助處理巢狀結構
- 注意邊框距離
- 範例如下：（在兩欄結構中，右邊欄位內有四欄）

![](https://i.imgur.com/dCCxwox.png =600x)

* 將 container 原本的兩個功能（限制整體寬度及置中、flexbox）分開成：
  * container：限制整體寬度及置中
  * row：設定 flexbox
```css=
.container{  
  /* ↓限制整體寬度及置中 */
  max-width: 1200px;
  margin: auto;
}
  /* ↓設定 flexbox */
.row{
  display: flex;
  flex-wrap: wrap;
}
```
- 加入 row 後的格線系統示意圖
![加入 row 之後的格線系統](https://i.imgur.com/9wnN66c.png)
- 加入 row 後運用在巢狀結構示意圖
![巢狀結構範例](https://i.imgur.com/nmmBPxA.png)


---

### 配合巢狀結構調整整體邊框距離
- 為方便辨識，將 row 加上橘紅邊框，col 加上藍色邊框，而 container 則加上背景色
- 由於想讓內容容器間有間隔距離所以在 col 上加 padding
- 在巢狀結構中會造成中間和側邊因為有兩層 col 而產生多餘 padding
- 如下圖範例：
  - 未調整邊框時，可以明顯看到中間交接處及右側的空白較大
  - 左側一格，中間三格，右側兩格（應該要中間兩格、右邊一格才對）

![](https://i.imgur.com/snZp7qW.png)

```html=
<div class="container">
    <div class="row"> 
        <div class="col-6"></div>  <!-- 用兩個 col-6 建立兩欄結構 -->
        <div class="col-6">
            <div class="row">  <!-- 在其中一個內容中加入四個 col-3 建立四欄結構 -->
                <div class="col-3"></div>
                <div class="col-3"></div>
                <div class="col-3"></div>
                <div class="col-3"></div>
            </div>
        </div>
    </div>
</div>
```
---
#### 解決辦法
1. 將 row 設定負數 margin 
   - 使第二層的 row 與第一層的 col 貼齊
   - 整體會超過 100% 
     - 因為 margin 是負數會把整體撐更大且不能用 border-box 調整
```css=
.container{
  max-width: 1200px;
  margin: auto;
}
.row{
  display: flex;
  flex-wrap: wrap;
  margin-left: -15px;
  margin-right: -15px;
}
```

    
![](https://i.imgur.com/7V1WbPt.png)

---

2. 給 container 做正數 padding，把寬度拉回來
   - 為避免寬度因為 padding 造成改變，給他一個 `box-sizing: border-box;` 固定
```css=
.container{
  max-width: 1200px;
  margin: auto;
  padding-left: 15px;
  padding-right: 15px;
  box-sizing: border-box;
}
.row{
  display: flex;
  flex-wrap: wrap;
  margin-left: -15px; 
  margin-right: -15px; 
}
```

![](https://i.imgur.com/vD2yfgQ.png)

---


### 第二種格線系統概念
- 僅適用在等欄寬分割，不可混搭
- col 都一樣，只使用一個 class 名稱
- 設定父層（row）的 class 名稱以表示欄數

```html=
<style>
  .row-cols-2 > .col {width: 50%;}            /* 2 欄版面 */
  .row-cols-3 > .col {width: 33.333333%;}     /* 3 欄版面 */
  .row-cols-4 > .col {width: 25%;}            /* 4 欄版面 */
  .row-cols-5 > .col {width: 20%;}            /* 5 欄版面 */
  .row-cols-6 > .col {width: 16.6666666%;}    /* 6 欄版面 */
</style>
<body>
  <div class="container">
    <div class="row row-cols-6">
      <div class="col">
        <img src="https://fakeimg.pl/300x200/ccc">
      </div>
      <div class="col">
        <img src="https://fakeimg.pl/300x200/ccc">
      </div>
      <div class="col">
        <img src="https://fakeimg.pl/300x200/ccc">
      </div>
      <div class="col">
        <img src="https://fakeimg.pl/300x200/ccc">
      </div>
      <div class="col">
        <img src="https://fakeimg.pl/300x200/ccc">
      </div>
      <div class="col">
        <img src="https://fakeimg.pl/300x200/ccc">
      </div>
  </div>
</body>
```
### 格線系統分開套用
1. 新增一個 css 檔案，裡面放格線系統，方便不同檔案間同時使用
2. 在 html 檔案，導入css link
3. 建議命名：grid.css

### 固定起手式 
* 通常 container 會設定 1440px 或 1200px
* 盡量不要讓數字出現小數點，不然會有精度問題
* 通常設定都會由此開始：
  * 手機 : .col-12 
  * 平板 : .col-md-4 or .col-md-3
* 所以可以建立快捷指令增加效率

## 小工具 Snippets
設定快捷指令（VScode)：
1. 選取所有快捷的部分
2. `command`+`shift`+`p` / `ctrl`+`shift`+`p`
3. input "snippet" -> "creat snippet"
4. 選使用語言`html`
5. 取名 -> 設定快捷鍵 -> 設定描述
6. 完成
 
編輯快捷指令 (VScode)：
![齒輪](https://i.imgur.com/e3rTX3F.png)
* 要選是什麼類型的快捷(ex.`html` `css`)

建立步驟：
1. 先用心智圖思考需要建立的快捷指令
2. 針對快捷指令建立系統，設計輸入層級


## 等比例區塊 （包含寬高）
- 普遍的狀況下，高度不能套用百分比距離
  - 因為父層高度由子層內容決定，子層內容高度又由父層決定
  - 如父層有高度的話才適合用百分比
  - 產生相互參照問題，很亂
- 可以用 `padding-bottom` 當作比例運算工具

### **當 padding 使用==百分比==作為單位時，計算的參考是父層的空間寬 (width)**
* 官方定義：The size of the padding as a percentage, relative to the width of the containing block.

例：
1. 父層寬為`1000px`，`padding-bottom: 25%;`就是父層寬 `1000px * 25% = 250px`
2. 父層寬為`1000px`，`padding: 25%;` 代表上下左右的`padding`都有父層寬的 25%
![padding使用百分比](https://i.imgur.com/O6LjQST.png =500x)
將％換算成px
```css=
.wrap{
      /* width: 1000px; */
      /* 拿掉寬度後，就以視窗大小來計算->等比例縮放*/
      border: 3px solid red;
    }
    .box{
      width: 25%;
      height: 0px;
      padding-bottom: 25%;
      /* 以百分比為單位的時候，參考父層的寬度 */
      background-color: #aaa;
    }
```


youtube 預設影片尺寸 `560*315`
如果要用兩欄版面，讓影片能夠等比例縮放
```css=
.wrap{
  /* width: 1000px; */
  display: flex;
  margin: auto;
  border: solid 2px blue;
}

.col{
  width: 50%;
}

.mv{
  width: 100%;
  padding-bottom: 56.25%;  /* 315/560 * 100 = 56.25 */
  background-color: #f00;
}
```

不專業計算法(?)

![](https://i.imgur.com/Kwv3plI.png =300x)

![](https://i.imgur.com/DYsazTF.png =300x)

- 若`a:b = c:d`的話，則`ad=bc`。

---
### 課後思考及問題
1. 格線系統尺寸設定
   - container, row, col 都只用來做框架設定
   - 內容容器的高若等於 100% ，對內容容器使用的 margin 及 padding 就會被算到內容高度裡
   - 此時在 row 上的預設值為 `align-item: stretch;` 所以內容會被撐開，如更改為其他屬性則高度會被壓回且套用設定。
   - 如果對內容容器使用 `box-sizing: border-box;` 尺寸就會連 padding 一起算進去
   - 結論：
     - 如要調整內容物件間距離，要在 col 上直接調整 padding 而不是內容容器調 margin
     - 如要調整內容物件的 padding 又要用 `height: 100%;`，最好使用 border-box
2. 若是 RWD 的排版內容差別巨大，則可以乾脆寫兩組同一區域，利用 display: none 讓某一組消失。