# 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;`)

- 主要容器:
- 格線容器(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 來輔助處理巢狀結構
- 注意邊框距離
- 範例如下:(在兩欄結構中,右邊欄位內有四欄)

* 將 container 原本的兩個功能(限制整體寬度及置中、flexbox)分開成:
* container:限制整體寬度及置中
* row:設定 flexbox
```css=
.container{
/* ↓限制整體寬度及置中 */
max-width: 1200px;
margin: auto;
}
/* ↓設定 flexbox */
.row{
display: flex;
flex-wrap: wrap;
}
```
- 加入 row 後的格線系統示意圖

- 加入 row 後運用在巢狀結構示意圖

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

```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;
}
```

---
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;
}
```

---
### 第二種格線系統概念
- 僅適用在等欄寬分割,不可混搭
- 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):

* 要選是什麼類型的快捷(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%

將%換算成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;
}
```
不專業計算法(?)


- 若`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 讓某一組消失。