---
# System prepended metadata

title: '分享 : 關於 CodeStyle 的那些大小事'

---



## :memo: 前言
在前端領域，CSS 除了靜態處理以外，還能夠處理許多靈活的動態效果，如果搭配框架，更能實現 for 迴圈、function 等邏輯，能夠應用的範圍逐年增加變廣。但在 CSS 能處理的範圍變廣的同時也增加維護上的難度，為了未來系統的發展性及穩定性，制定語法規範恐怕是每個團隊遲早會遇到的課題，在這邊由不才為大家進行簡單介紹~。對於內容有任何補充或疑惑，歡迎大家踴躍提出一起討論，感謝 !

## :memo: 為何需要製作 codestyle guideline
* 讓各個團隊成員可以在第一時間直接接手其他成員的專案。
* 在進行協作的時候保持一致性，不會因為命名問題導致 css 被重複利用，或沒被使用。
* 能夠將各個重複性高的程式碼分為元件以及組件，直接 import 使用。
* 未來在大型改版或長期維護能夠更省力。

從頭開始進行進行 codestyle 制定一定會遇到許多阻力，但在之後開始多人協作、維護大型專案的時候， 制定 codestyle 的方便性會有很明顯的感受。
如果一開始沒有方向的話，推薦可以先參考看看其他公司的 codestyle。
例如: **[pixnet](https://pixnet.github.io/frontend-guideline/)**

## :memo: 規範的方向

### | 編輯器設定
確保團隊成員的套件、空格、輔助工具等版本與設定均為一致。

**:arrow_right: 關於寫法 :**

eg:
* 使用 1 個空格的 soft tabs
* 這是唯一可以保證程式碼在任何環境下，render 結果一致的方法。
* 幫選擇器分組時，獨立的選擇器自成一行。
* 左大括號左邊留 1 個空白來提升可讀性。
* 右大括號應另起新行。

**:arrow_down: 推薦 VS 套件 :arrow_down:**

### :arrow_right: Prettier - Code formatter

Prettier 能夠解析代碼，使用自己設定的規則來重新整理出格式規範的代碼。

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

---

### :arrow_right: ESLint

ESLint 是一個 Javascript Linter，用來確保程式碼品質在一定的水準之上，常常結合 Prettier 一起應用。

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


* 使用
    * 如果已經在項目中使用 ESLint，並且想要只通過單獨一條命令來執行所有的代碼檢查的話，可以使用 ESLint 來代為運行 Prettier。

    * 只需要使用 eslint-plugin-prettier 來添加 Prettier 作為 ESLint 的規則配置。

```
npm add --dev prettier eslint-plugin-prettier

.eslintrc.json
```
---

### :memo: 路徑分類
確保團隊成員在執行的所有專案路徑與結構均為一致。
普遍區分方式: 用產品功能進行區分，將各個通用及獨立功能樣進行區別與分類。
#### eg:

```
├── portal                         // 桌機版
        ├── KD001-02/
            ├── assets/                // 靜態資源
                └── images/
            ├── components/            // 公共元件
            ├── style/                 // SCSS
                ├── fonts
                ├── index.scss         // import 版型內共用的 scss
                ├── notice.scss        // style scope
                ...
                └── common.scss
            └── views/                 // 頁面組件
                ├── betHistory/        // 投注記錄
                ├── deposit/           // 存款
                ├── event/             // 優惠活動
                ├── home/              // 首頁
                    ├── component/
                    └── Home
                ├── lobby/             // 遊戲大廳
                ├── my/                // 我的頁面
                ├── notice/            // 通知
                ├── serviceCenter/     // 客服中心
                ├── siteMail/          // 站內信
                └── withdraw/          // 取款
        └── KD001-03
            ├── assets/
            ├── router/ 
            ├── style/ 
            └── views/
                └── event/ 
            ....
    ├── mobile                        // 手機版
        ....
```


### :memo: 命名規範

**:arrow_right: BEM 規則:**

* Block : 通常為語法語意或是區塊名稱。
    * header, nav, subnav, menu, submenu, main, aside, footer
* Element : 為 block 的子元素，描述 block 的內容。
    * structure type: header, main, contentm, footer
    * text type: txt, link
    * form type: form, input, label
    * table type: table, column, row, cell
    * list type: list, item, filed
    * button type: button
* Modifier : 為區塊與元素描述現在的狀態 ( small、middle、big )。 
    * status: primary, success, warning, error, active
    * size: small, middle, big
    * container: box, wrap
* type-block(` header、menu、nav `)__element(` item、product、content、inner-content `)_modifier(` small、middle、big `) 是 BEM 的基本型。
> 中劃線 - ：僅作為連字符使用，對某個塊或者某個子元素的補充說明中間的連接記號。
> 雙下劃線 __ ：雙下劃線用來連接塊和子元素。
> 單下劃線 _ ：單下劃線用來描述一個塊或者塊的子元素的一種狀態。
```
// wrong
.list{}
.list.select{}
.list .item{}
.list .item.active{}


// correct  
.list{}
.list_select{}
.list__item{}
.list__item_active{}
```
**:arrow_right: OOCSS（Object Oriented CSS）**

* Separation of Structure from Skin：分離結構與樣式。結構像是元素的大小，樣式像是顏色等。
* Separation of Containers and Content：分離 HTML 與 CSS，意即盡量將可共用的樣式提取到單獨的 class 以供使用。
* 目的 : 使用 class 撰寫樣式，每個 class 有其各自用途。

``` 
<button class="btn btn-small btn-primary"></button> 
```
> * btn：規範按鈕的預設樣式。
> * btn-small：規範按鈕的大小，在這裡是指小的。可能還有 btn-large（可能是大的）、btn-medium（可能是中的）。
> * btn-primary：規範按鈕的顏色，在此「primary」表示暗示使用者作出行動的主色，例如橘色。可能還有 btn-default（可能是白色）、btn-disabled（可能是灰色）。

**:arrow_right: SMACSS**
* 通則 :
    * 結構分類：Base、Layout、Module、State、Theme。
    * 命名規則：id 與 class 受限制地使用、名稱使用 dash 分隔。

* 結構 :
    * Base：網頁的基本樣式，包含 CSS Reset。
    * Layout：將網頁切割成不同區塊（元素），區塊若為唯一出現可用 id，例如 `#tab`；若會重複出現則用 class，其中，class 可串連，例如 `.tab-default.tab-fancy`。
    * Module：同 Layout，也是頁面上的區塊，但比較像是區塊的內容，只能使用 class 命名，並且使用 dash 分隔，例如 `.tab-item`。
    * State：描述元件的狀態，例如：`tab-item active` 的 active。
    * Theme：針對網站主視覺而定義的 Layout 或 Module 的樣式。 例如 `.tab-dark`。

[SMACSS參考資料](https://medium.com/@savemuse/smacss-%E6%95%99%E5%AD%B8-c94e858aa762)
[BEM參考資料](https://juejin.cn/post/6844903672162304013)
[其他參考資料](https://cythilya.github.io/2018/06/05/css-methodologies/)
### :memo: CSS 屬性順序
1. 重要性或影響性高的屬性放前面，例如：Positioning 區塊 放 Box Model 區塊前面。
2. 相依性的屬性要排序，例如：position 放 top 前面。
3. 相關性高的放一起，例如：flex 相關屬性。
```css=
.sample {

  /* Content */
  content: ".";
  
  /* Positioning */
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 100;

  /* Box-model */
  display: flex;
  justify-content: center;
  align-items: center;
  float: right;
  margin-top: 16px;
  padding-left: 16px;
  width: 100px;
  height: 100px;

  /* Typography */
  font: normal 13px "Helvetica Neue", sans-serif;
  line-height: 1.5;
  color: #333;
  text-align: center;

  /* Visual */
  background-color: #f5f5f5;
  border: 1px solid #e5e5e5;
  border-radius: 3px;

  /* Misc */
  opacity: 1;
}
```
### :memo: 組件與元件

製作元件與組件的步驟，一般會由大架構開始慢慢由大到小進行拆解，一開始不知道方向的時候，大部分的設計團隊都會參考 [Google  Material Design](https://material.io/design) 以及 [Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/ios/overview/themes/)。
這邊將以 google material 為例子，進行簡單的流程介紹 ~

**:arrow_right: 流程 :**
參考 material design 將系統由大開始分成:

1. layout
2. color
3. font
4. icon

以 layout 為例，將畫面開始進行切割。

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

1. header
2. side-navigation
3. body

將以下區塊分類後，進行 layout 的設定以及各個區塊內 component 的歸類。
關於 layout 的設定，以 material design guideline 舉例 : 

####  1. elements 間的設定，統一採用 8 的倍數。

設定倍數規則能夠幫助團隊在後續的更細節的組件定義的部分，有更明確的方向並避免產生主觀混亂。

![](https://i.imgur.com/9xWK3Ua.gif)

####  2. 制定 media screen 標準

因每個團隊的產品特性都不同的緣故，就不進行舉例。
如果想參考市面上使用度最廣泛的範例的話，可參考 [bootstrap media](https://getbootstrap.com/docs/4.1/layout/grid/) 的規則。

補充資料 : 關於 [響應式的參考](https://web.dev/responsive-web-design-basics/)



**:arrow_right: 元件的分類**

在將區塊劃分後，開始整理內部的元件，並開始將元件粗部歸類。

e,g : 

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



**:arrow_right: 元件 :** 
* 單有的元素，像是針對 button 、 input 、 image 等等，進行樣式的分類與統整。

**:arrow_right: 組件 :**
* 由複數的元件所組成，像是下拉式選單、bannerslider、form等等，皆為組件的範圍內。

**:arrow_down: 範例 :**

#### 元件範例
![](https://i.imgur.com/To9JOwa.png)
> * `button` 結構一律為 `button` 包 `span`。
> * 範例使用 BEM 命名法，用 Block 進行區分。

---

#### 組件範例
![](https://i.imgur.com/oIj3wkW.png)
> * 上述例子為下拉式選單 `dropdown`，由選單 `menu` 與按鈕 `button` 兩個元件組成。
> * 透過各個元件的 Block 可以清楚理解各個元件的配置以及組件。


##### 網頁設計模組化參考: 
[UIKIT](https://getuikit.com/docs/introduction)
[元件化 - 步驟解構](https://uiclub.tw/2021/09/03/how-to-write-a-uidesign-guideline/)

### :memo: SASS/SCSS 轉 CSS 工具分享

:arrow_right: **為什麼推薦 SCSS ?**

SCSS 是由 CSS 衍生的巢狀規則的擴充框架，推薦使用 scss 的原因為 : 

1. 與 SASS 相比與 CSS 比較相像，適應阻力較低。
2. 巢狀式寫法將層級的區分顯示的更明顯，且在維護上能夠更靈活。
3. scss 支援許多語法 ( e,g, @for 、 @function ... 等)，減少重工情況。
4. scss 擁有完善的編譯工具資源，例如 gulp、webpack，而這些框架能提供的功能為 : 
    * 在編譯過程中，有語法錯誤會偵測並跳出錯誤視窗顯示錯誤訊息及位置。
    * 編譯完後只要存檔就能自動同步畫面而不用 F5 。
    * 編譯完存檔後會自動加各瀏覽器前綴，並可以為各個瀏覽器進行客製化。 



**:arrow_right:  編譯工具的介紹 :**

編譯工具的部分，世面上已有不少公認的編譯工具，而這邊介紹的部分，是用 node.js 的 gulp。

**[gulp 使用介紹](https://hackmd.io/lIGRZc7ITk-qhQerGQ9gWw?both)**

---
#### 參考標準 : 
[Google CodeStyle Guideline](https://google.github.io/styleguide/htmlcssguide.html)
[pixnet codestyle guideline](https://pixnet.github.io/frontend-guideline/)
[CSS Guideline](https://cssguidelin.es/#the-importance-of-a-styleguide)
[Bootstrap CodeStyle Guideline](https://codeguide.co/#css)