# 05. SCSS 程式開發標準
文件建立人員: 蔡勝豐
文件建立時間: 2021/02/07 6:25 PM
最後修改人員: 蔡勝豐
最後修改時間: 2021/03/08 6:25 PM
文件類型: 開發標準文件
文件版本: v 1.0
# 目的
1. 規範SCSS(CSS)統一格式
2. 此文件目的是在於幫助大家更好書寫及維護SCSS
# 範圍
1. 請寫下此技術文件適用影響之範圍
# 修訂歷程
| 修訂人員 | 修訂內容 |修訂日期 | 版本 |
| -------- | -------- | -------- | -------- |
| 蔡勝豐 | 初版 | 20210308 | 1.0.0
# 1.命名格式
* 以有意義的名詞或形容詞進行命名
* 名詞或形容詞首字為小寫
* 各詞之間用"-"來進行連接
# 2.語法格式
* 使用兩個空格代表縮進,而非使用Tab
* 理想上,每行保持為100個字符寬度
* 正確書寫多行CSS規則
* 有意義的使用空格
以 font-family 屬性為例:
```sass
// 推薦方式
.foo{
display: block;
overflow: hidden;
padding: 0 1em;
}
// 不推薦方式
.foo {
display: block; overflow: hidden;
padding: 0 1em;
}
```
2-1.[字符串](#1-1.字符串)
2-2.[數值](#1-2.數值)
2-3.[顏色](#1-3.顏色)
2-4.[列表](#1-4.列表)
2-5.[Maps](#1-5.Maps)
2-6.[CSS規則集](#2-6.CSS規則集)
2-7.[聲明順序](#2-7.聲明順序)
### 2-1.字符串
CSS 中不要求字符串必須用引號包裹,甚至是字符串中包含空格的,因此 Sass 也不強制要求字符串必須被引號包裹。
話雖如此,不強制要求字符串被引號包裹的畢竟是少數,所以在 Sass 中字符串應該始終被單引號所包裹,理由如下:
* 如果顏色名不被引號包裹,將會被解析為顏色值,顯然這會導致嚴重問題;
* 大多數的語法高亮機制將會因未被引號包裹的字符串而罷工;
* 提高可讀性;
* 沒有正當理由不去用引號包裹字符串。
```sass
//推薦方式
$font-stack: 'Helvetica Neue Light', 'Helvetica', 'Arial', sans-serif;
//不推薦方式
$font-stack: "Helvetica Neue Light", "Helvetica", "Arial", sans-serif;
//不推薦方式
$font-stack: Helvetica Neue Light, Helvetica, Arial, sans-serif;
```
URL 最好也用引號包裹起來:
```sass
// 推薦方式
.foo {
background-image: url('/images/kittens.jpg');
}
// 不推薦方式
.foo {
background-image: url(/images/kittens.jpg);
}
```
### 2-2.數值
在 Scss中,數字類型包括了長度、持續時間、頻率、角度等等無單位數字類型。Scss 允許在運行中計算這些度量值。
* [零值](#零值)
* [單位](#單位)
* [計算](#計算)
#### 2-2-1.零值
數字小於 1 時,應該在小數點前寫出 0.,永遠不要顯示小數尾部的 0。
```sass
// 推薦方式
.foo {
padding: 2em;
opacity: 0.5;
}
// 不推薦方式
.foo {
padding: 2.0em;
opacity: .5;
}
```
#### 2-2-2.單位
定義長度時,0 後面不需要加單位。
```sass
// 推薦方式
$length: 0;
// 不推薦方式
$length: 0em;
```
在 Scss 中最常見的錯誤,是簡單地認為單位只是字符串,認為它會被安全的添加到數字後面。這雖然聽起來不錯,但卻不是單位正確的解析方式。
將一個單位添加給數字的時候,實際上是讓該數值乘以 *1 個單位:
```sass
$value: 42;
// 推薦方式
$length: $value * 1px;
// 不推薦方式
$length: $value + px;
```
要刪除一個值的單位,你需要除以相同類型的 1 單位:
```sass
$length: 42px;
// 推薦方式
$value: $length / 1px;
// 不推薦方式
$value: str-slice($length + unquote(''), 1, 2);
```
#### 2-2-3.計算
最高級運算應該始終被包裹在括號中。
這麼做不僅是為了提高可讀性,也是為了防止一些 Scss 強制要求對括號內內容計算的極端情況。
```sass
// 推薦方式
.foo {
width: (100% / 3);
}
// 不推薦方式
.foo {
width: 100% / 3;
}
```
### 2-3.顏色
顏色在 CSS 中佔有重要地位。當涉及到操縱色彩時,Sass 通過提供少數的函數功能。
* [顏色格式](#顏色格式)
* [顏色和變量](#顏色和變量)
#### 2-3-1.顏色格式
為了盡可能簡單地使用顏色,建議顏色格式要按照以下順序排列:
CSS 顏色關鍵字
十六進制,大寫並儘可能簡寫
RGB 值
HSL 值
```sass
// 推薦方式
.foo {
color: red;
}
// 不推薦方式
.foo {
color: hsl(300, 100%, 100%);
}
```
#### 2-3-2.顏色和變量
當一個顏色被多次調用時,最好用一個有意義的變量名來保存它。
```sass
$sass-pink: #c69;
```
就可以在任何需要的地方隨意使用這個變量了。
不過,如果你是在一個主題中使用,不建議固定的使用這個變量。
可以使用另一個標識方式的變量來保存它。
```sass
$main-theme-color: $sass-pink;
```
簡單來說就是不要將命名寫死,而是根據功能情境來描寫。
### 2-4.列表
列表就是 Sass 的數組。列表是一個一維的數據結構,用於保存任意類型的數值(包括列表,從而產生嵌套列表)。
列表需要遵守以下規範:
* 除非列表太長不能寫在 100 字符寬度的單行中,否則應該始終單行顯示
* 除非適用於CSS,否則應該始終使用逗號作為分隔符
* 除非為空或者嵌套在另一個列表中,否則始終不要使用括;
* 始終不要添加尾部的逗號
```sass
// 推薦方式
$font-stack: 'Helvetica', 'Arial', sans-serif;
// 不推薦方式
$font-stack:
'Helvetica',
'Arial',
sans-serif;
// 不推薦方式
$font-stack: 'Helvetica' 'Arial' sans-serif;
// 不推薦方式
$font-stack: ('Helvetica', 'Arial', sans-serif);
// 不推薦方式
$font-stack: ('Helvetica', 'Arial', sans-serif,);
```
當需要給列表添加一個新列表項時,請遵守其提供的 API,不要試圖手動給列表添加列表項。
```sass
$shadows: 0 42px 13.37px hotpink;
// 推薦方式
$shadows: append($shadows, $shadow, comma);
// 不推薦方式
$shadows: $shadows, $shadow;
```
### 2-5.Maps
在 Sass 中,樣式開發者可以使用 map 這種數據結構。但不建議使用 map 存儲複雜數據類型。
map 的使用應該遵循下述規範:
* 冒號 : 之後添加空格
* 左開括號 ( 要和冒號 : 寫在同一行
* 如果鍵是字符串(99% 都是字符串),則使用括號包裹起來
* 每一個鍵值對單獨一行
* 每一個鍵值對以逗號 , 結尾
* 為最後一個鍵值對添加尾部逗號 ,,方便添加新鍵值對、刪除和重排已有鍵值對
* 單獨一行書寫右閉括號 )
* 右閉括號 ) 和分號 ; 之間不使用空格和換行
```sass
// 推薦方式
$breakpoints: (
'small': 767px,
'medium': 992px,
'large': 1200px,
);
// 不推薦方式
$breakpoints: ( small: 767px, medium: 992px, large: 1200px );
```
### 2-6.CSS規則集
* 相關聯的選擇器寫在同一行;不相關聯選擇器分行書寫
* 最後一個選擇器和左開大括號 { 中間書寫一個空格
* 每個聲明單獨一行
* 冒號 : 後添加空格
* 所有聲明的尾部都添加一個分號 ;
* 右閉大括號 } 單獨一行
```sass
// 推薦方式
.foo, .foo-bar,
.baz {
display: block;
overflow: hidden;
margin: 0 auto;
}
// 不推薦方式
.foo,
.foo-bar, .baz {
display: block;
overflow: hidden;
margin: 0 auto }
```
添加與 CSS 相關的規範時,我們需要注意:
* 本地變量在其他任何變量之前聲明,並和其他聲明用空行分隔開
* 不需 @content 的混合宏在放在其他聲明之前
* 嵌套選擇器在新行聲明
* 需要 @content 的混合宏在嵌套選擇器後聲明
* 右閉大括號 } 上一行無需空行
```sass
.foo, .foo-bar,
.baz {
$length: 42em;
@include ellipsis;
@include size($length);
display: block;
overflow: hidden;
margin: 0 auto;
&:hover {
color: red;
}
@include respond-to('small') {
overflow: visible;
}
}
```
### 2-7. 聲明順序
主要以類型進行排序
```sass
.foo {
height: 100px;
width: 100px;
overflow: hidden;
position: absolute;
bottom: 0;
right: 0;
background: black;
color: white;
font-weight: bold;
font-size: 1.5em;
}
```
# 3.常量
命名將以全大寫方式書寫
```sass
// 推薦方式
$CSS_POSITIONS: top, right, bottom, left, center;
```
# 4.註釋
該註釋的內容
* 一個文件的結構或者作用
* 規則集的目標
* 使用幻數背後的目的
* CSS 聲明的原因
* CSS 聲明的順序
* 方法執行背後的邏輯思維
### 4-1. 寫註釋
* 以 C 風格註釋來進行CSS塊的核心的註釋
* 不能明顯看出意義的地方都應該註釋
* 註釋 SCSS 的一個特定部分時,應該使用SCSS單行註釋
```sass
/**
* Helper class to truncate and add ellipsis to a string too long for it to fit
* on a single line.
* 1. Prevent content from wrapping, forcing it on a single line.
* 2. Add ellipsis at the end of the line.
*/
.ellipsis {
white-space: nowrap; /* 1 */
text-overflow: ellipsis; /* 2 */
overflow: hidden;
}
```
### 4-2. 文檔
每一個旨在代碼庫中復用的變量、函數、混合和佔位符,都應該使用 SassDoc 記錄下來作為全部 API 的一部分。
註:需要三個斜槓 ```/```
SassDoc 主要有兩個作用:
* 作為公有或私有 API 的一部分,在所有的地方使用一個註釋系統強制標準化註釋。
* 通過使用任意的 SassDoc 終端(CLI tool、Grunt、 Gulp、Broccoli、Node…),能夠生成 API 文檔的 HTML 版本。
```sass=
/// Mixin helping defining both `width` and `height` simultaneously.
///
/// @author Hugo Giraudel
///
/// @access public
///
/// @param {Length} $width - Element's `width`
/// @param {Length} $height ($width) - Element's `height`
///
/// @example scss - Usage
/// .foo {
/// @include size(10em);
/// }
///
/// .bar {
/// @include size(100%, 10em);
/// }
///
/// @example css - CSS output
/// .foo {
/// width: 10em;
/// height: 10em;
/// }
///
/// .bar {
/// width: 100%;
/// height: 10em;
/// }
@mixin size($width, $height: $width) {
width: $width;
height: $height;
}
```
# 5.結構
將SCSS及CSS已有意義的方式分拆為不同等級的code librery並以資料夾進行分類,形成Css樣式表
```
sass/
|
|– base/
| |– _reset.scss # Reset/normalize
| |– _typography.scss # Typography rules
| ... # Etc…
|
|– components/
| |– _buttons.scss # Buttons
| |– _carousel.scss # Carousel
| |– _cover.scss # Cover
| |– _dropdown.scss # Dropdown
| ... # Etc…
|
|– layout/
| |– _navigation.scss # Navigation
| |– _grid.scss # Grid system
| |– _header.scss # Header
| |– _footer.scss # Footer
| |– _sidebar.scss # Sidebar
| |– _forms.scss # Forms
| ... # Etc…
|
|– pages/
| |– _home.scss # Home specific styles
| |– _contact.scss # Contact specific styles
| ... # Etc…
|
|– themes/
| |– _theme.scss # Default theme
| |– _admin.scss # Admin theme
| ... # Etc…
|
|– utils/
| |– _variables.scss # Sass Variables
| |– _functions.scss # Sass Functions
| |– _mixins.scss # Sass Mixins
| |– _helpers.scss # Class & placeholders helpers
|
|– vendors/
| |– _bootstrap.scss # Bootstrap
| |– _jquery-ui.scss # jQuery UI
| ... # Etc…
|
|
– main.scss # primary Sass file
```
* [Base](#Base)
* [Layout](#Layout)
* [Components](#Components)
* [Pages](#Pages)
* [Themes](#Themes)
* [Utils](#Utils)
* [Vendors](#Vendors)
* [VendorExtensions](#VendorExtensions)
* [Main](#Main)
### Base
`base/` 文件夾存放項目中的模板文件。在這裡,可以找到重置文件、排版規範文件或者一個樣式表
(通常命名為`_base.scss`)——定義一些 HTML 元素公認的標準樣式。
* `_base.scss`
* `_reset.scss`
* `_typography.scss`
### Layout
`layout/` 文件夾存放構建網站或者應用程序使用到的佈局部分。該文件夾存放網站主體(頭部、尾部、導航欄、側邊欄…)的樣式表、柵格系統甚至是所有表單的 CSS 樣式。
* `_grid.scss`
* `_header.scss`
* `_footer.scss`
* `_sidebar.scss`
* `_forms.scss`
* `_navigation.scss`
### Components
對於小型組件來說,有一個 `components/` 文件夾來存放。相對於 `layout/` 的宏觀(定義全局線框結構),`components/` 更專注於局部組件。該文件夾包含各類具體模塊,基本上是所有的獨立模塊,比如一個滑塊、一個加載塊、一個部件… 由於整個網站或應用程序主要由微型模塊構成,`components/` 中往往有大量文件。
### Pages
如果頁面有特定的樣式,最好將該樣式文件放進`pages/`文件夾並用頁面名字。例如,主頁通常具有獨特的樣式,因此可以在 `pages/` 下包含一個 `_home.scss` 以實現需求。
* `_home.scss`
* `_contact.scss`
### Themes
`themes/`用來儲存不同主題
* `_theme.scss`
* `_admin.scss`
### Utils
`utils/` 文件夾包含了整個項目中使用到的 Sass 輔助工具,這裡存放著每一個全局變量、函數、混合宏和佔位符。
該文件夾的經驗法則是,編譯後這裡不應該輸出任何 CSS,單純的只是一些 Sass 輔助工具。
* `_variables.scss`
* `_mixins.scss`
* `_functions.scss`
* `_placeholders.scss` (通常命名為_helpers.scss)
### Vendors
用來存放所有外部庫和框架(Normalize、Bootstrap、jQueryUI…)的 CSS 文件。
* `_normalize.scss`
* `_bootstrap.scss`
* `_jquery-ui.scss`
* `_select2.scss`
### VendorExtensions
用來存放重寫的外部庫和框架的CSS文件,並使用相同的名字命名。
* `vendors-extensions/_boostrap.scss`
### Main
主文件(通常寫作 `main.scss`)應該是整個代碼庫中唯一開頭不用下劃線命名的 Sass 文件。除 @import 和註釋外,該文件不應該包含任何其他代碼。
文件應該按照存在的位置順序依次被引用進來:
* `vendors/`
* `utils/`
* `base/`
* `layout/`
* `components/`
* `pages/`
* `themes/`
為了保持可讀性,主文件應遵守如下準則:
* 每個 @import 引用一個文件
* 每個 @import 單獨一行
* 從相同文件夾中引入的文件之間不用空行
* 從不同文件夾中引入的文件之間用空行分隔
* 忽略文件擴展名和下劃線前綴
```
@import 'vendors/bootstrap';
@import 'vendors/jquery-ui';
@import 'utils/variables';
@import 'utils/functions';
@import 'utils/mixins';
@import 'utils/placeholders';
```
# 6.組件
幾乎所有的接口都可以被視為小組件,而且強烈建議堅持這種模式。這不僅僅會精簡整個項目中 CSS 的代碼量,而且也會比維護一個到處無邏輯的爛攤子容易得多。
組件可以是任意的,前提是遵循以下規範:
* 可以做一件事,只做一件
* 在整個項目中可以重用,具有可復用性
* 各自獨立
# 7. 條件語句
請遵守下述準則:
* 除非必要,不然不需要括號
* 務必在 @if 之前添加空行
* 務必在左開大括號 { 後換行
* @else 語句和它前面的右閉大括號 } 寫在同一行
* 務必在右閉大括號 } 後添加空行,除非下一行還是右閉大括號 },那麼就在最後一個右閉大括號 } 後添加空行
```sass
// 建議寫法
@if $support-legacy {
// …
} @else {
// …
}
// 不建議寫法
@if ($support-legacy == true) {
// …
}
@else {
// …
}
```
* 通常將變量置於語句的左側,而將結果置於右側。
```sass
// 建議寫法
@if $value == 42 {
// …
}
// 不建議寫法
@if 42 == $value {
// …
}
```
* 當使用條件語句並在一些條件下有內聯函數返回不同結果時,始終要確保最外層函數有一個 @return 語句。
```sass=
// 建議寫法
@function dummy($condition) {
@if $condition {
@return true;
}
@return false;
}
// 不建議寫法
@function dummy($condition) {
@if $condition {
@return true;
} @else {
@return false;
}
}
```
# 相關檔案與連結
1. 上傳相關檔案或附上檔案連結