## :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 能夠解析代碼,使用自己設定的規則來重新整理出格式規範的代碼。

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

* 使用
* 如果已經在項目中使用 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 為例,將畫面開始進行切割。

1. header
2. side-navigation
3. body
將以下區塊分類後,進行 layout 的設定以及各個區塊內 component 的歸類。
關於 layout 的設定,以 material design guideline 舉例 :
#### 1. elements 間的設定,統一採用 8 的倍數。
設定倍數規則能夠幫助團隊在後續的更細節的組件定義的部分,有更明確的方向並避免產生主觀混亂。

#### 2. 制定 media screen 標準
因每個團隊的產品特性都不同的緣故,就不進行舉例。
如果想參考市面上使用度最廣泛的範例的話,可參考 [bootstrap media](https://getbootstrap.com/docs/4.1/layout/grid/) 的規則。
補充資料 : 關於 [響應式的參考](https://web.dev/responsive-web-design-basics/)
**:arrow_right: 元件的分類**
在將區塊劃分後,開始整理內部的元件,並開始將元件粗部歸類。
e,g :

**:arrow_right: 元件 :**
* 單有的元素,像是針對 button 、 input 、 image 等等,進行樣式的分類與統整。
**:arrow_right: 組件 :**
* 由複數的元件所組成,像是下拉式選單、bannerslider、form等等,皆為組件的範圍內。
**:arrow_down: 範例 :**
#### 元件範例

> * `button` 結構一律為 `button` 包 `span`。
> * 範例使用 BEM 命名法,用 Block 進行區分。
---
#### 組件範例

> * 上述例子為下拉式選單 `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)