Sass - liveSass 設定與介紹

簡介

Sass(Syntactically Awesome StyleSheets)是 CSS 的 preprocesser(預前處理器),誕生於 2007 年,是最早的 CSS 預處理器,目的是在撰寫 CSS 時減少反覆重工動作及更好維護樣式結構,撰寫 Sass 需進行編譯成原生的 CSS 才能使用(瀏覽器看不懂 Sass),需預前經過編譯這個動作成原生 CSS 瀏覽器才能閱讀。

Sass 優點

CSS 不是一種程式語言,沒有流程控制、函式等等的功能,Sass 除了可以使用嵌套規則(nested rules)、繼承(extends)、混合(mixins),也可以稱為 CSS 的程式語言(SassScript),它可以使用變數(variables)、流程控制(flow control)、函式(functions)等等,並且完全兼容 CSS 語法(scss),撰寫起來親和更為彈性,樣式碼較短且強大優雅,由於 Sass 維護起來比 CSS 容易,很適合用來開發專案,例如:Bootstrap 是使用 Sass(scss)開發出來的專案框架。

  • 完全相容 CSS(scss)。
  • 重複模組化的設計(mixins)。
  • 減少重工的流程,維護起來容易。
  • 擁有數學加減乘除的計算。
  • CSS 的程式語言,例如:變數(variables)、函式(functions)、流程控制(flow control)、map 物件等等。

Sass 缺點

CSS 巢狀階層運用需謹慎,否則即使簡短的樣式碼也可能會解譯成 CSS 龐然大物,例如選擇器太長的問題。

CSS 會遇到的問題…

在撰寫 CSS 時,常常為了一個區塊間的樣式使用了重複性的動作,例如使用 .menu 去階層選擇,此時會遇到重複的動作,若要修改 .menu 成其他名稱,就要一一修改,Sass 可以使用巢狀寫法來解決問題,下面的範例為 scss,Sass 的其中一種。

  • css
.menu {
list-style: none;
}
.menu li {
float: left;
}
.menu a {
display: block;
}
  • scss
.menu {
list-style: none;
li {
float: left;
a {
display: block;
}
}
}

Sass 有兩種語法

  • 第一種是比較歷史較久的語法稱為 sass
    它不需要括號、也不用分號,使用縮進語法(TAB)用換行和縮進來分隔屬性,副檔名是sass

  • 第二種是較年輕的語法稱為 scss
    它是 CSS3 語法的擴充版,更接近 CSS 的原生面貌,使用塊語法(BLOCK),寫法跟 CSS3 一樣有親和性,也是目前主流的語法,需要括號、分號,副檔名是scss

它們都稱為 Sass。Sass 還有其他兄弟叫 Less、Stylus,三兄弟的概念相同,寫法有些不同。

如何開始使用 Sass?

  1. 環境:安裝 Node.js
  2. 管理 Node.js :安裝 nvm
  3. VScode 擴充套件:Live Server、Live Sass Compiler,以下為 settings.json 要設定。
// Live Sass Compiler -----------------------------------------------------------------------------------------
"liveSassCompile.settings.formats": [
// 輸出 css 檔案
{
"format": "expanded",
"extensionName": ".css",
// "savePath": "~/../css",
"savePath": "/css"
},
// 輸出 min.css 壓縮檔案
{
"format": "compressed",
"extensionName": ".min.css",
// "savePath": "~/../dist",
"savePath": "/dist"
}
],
// 排除區域,這些路徑下不會轉成Sass
"liveSassCompile.settings.excludeList": ["**/node_modules/**", ".vscode/**"],
// 產生 Map 檔,Sass 跟 CSS 做對應行數,false => 不啟動
"liveSassCompile.settings.generateMap": false,
// 自動加入前綴(Prefix => moz、webkit、o、ms),市佔率大於 1% 或 最新的 2 個版本的瀏覽器
"liveSassCompile.settings.autoprefix": ["> 1%", "last 2 versions"],

匯入、匯出檔案

Sass 能分割成數個檔案並且再組合成單一檔案,Sass 稱這些檔案為區塊(partials),要告知 Sass 不想要匯出這些區塊成單獨 CSS 檔案,必須將區塊檔案用底線 _ 字元開頭。

@import

CSS 有一個我特別不常用的特性,即 @import 規則,它允許在一個 css 文件中導入其他 css 文件。然而,只有執行到 @import 時,瀏覽器才會去下載其他 CSS 文件,這會影響頁面加載速度。

SASS 也有一個 @import 規則,但不同的是,Sass 的 @import 規則在生成 css 文件時就把相關文件導入進來。這意味著所有相關的樣式被歸納到了同一個 css 文件中,而無需發起額外的下載請求。@import 尋找 Sass 文件副檔名為 scsssass 並將其導入。如果只想做匯入至其他 Sass 檔案,而不匯出成 CSS,以下有兩種方式:

  • 檔名前面可以加上 _,只做匯入給其他檔案使用。
  • 或是直接忽略 _.scss.sass
// 只要有 _檔名的檔案,不會編譯成 CSS
@import '_grid.scss';

// 可以忽略 _ 和 .scss 寫成以下,這樣只會匯入 _grid.scss,一樣不會編譯成 CSS
@import 'grid';

// Sass 允許同時導入多個文件,但一般建議一個 @impot 一個 sass 檔
@import 'grid', 'variables';

在以下情況下,@import 僅作為普通的 CSS 語句,不會導入任何 Sass 文件。

  • 被導入文件是 .css 結尾
  • 被導入文件是一個 URL 位置以 http:// 開頭
  • 被導入文件是 css 的 url() 值
  • @import 包含 media queries

也就是說不能用 Sass 的 @import 直接導入一個原始的 css 文件,換句話說 Sass 可以使用 css @import,但是不吃 .css 檔名,它只吃 .scss.sass檔名。

// 以下都無法載入 Sass,Sass 會拒絕
@import 'foo.css';
@import 'foo' screen;
@import 'http://foo.com/bar';
@import url(foo);

註解

Sass 支援標準的 CSS 多行註解 /* */,以及單行註解 //,編譯後,前者會輸出在 CSS 文件中,後者則不會。

插值語法

使用變數與其它語句組合時,Sass 有提供插值語法 #{$var},插值語法也可以使用在註解裡面。

// sass
$name: foo;
$attr: border;
p.#{$name} {
#{$attr}-color: blue;
}
// css
p.foo {
border-color: blue;
}

// sass
$version: '1.2.3';
/* 此版本為 #{$version} 編譯 */

// css
/* 此版本為 1.2.3 編譯 */

數學運算

Sass 可以做數學計算,且不會耗效能。CSS 的 calc() 則是在解析網頁文件階段處理計算,因此會耗掉些些記憶體。

  • 加、減、乘、除,只有除法需要括號。
  • 除法分母的單位,分母無單位可以做一般除法,若分子、分母兩者有單位(需要括號包住),單位會被抵銷,變成倍數。
$width: 1000px;
$font-size: 12px;
$line-height: 30px;
p {
// 除法無效
font: 10px / 8px;
// 變數可以使用除法
width: $width / 2;
// 使用()進行除法
height: (500px / 2);
// 使用 round 函式
line-height: round(2.5) / 2;
// 運算式可以直接用除法
margin-left: 5px + 8px / 2px;
}

不想做除法又想使用 /,可以使用插值語法將變數包在裡面,可以避免執行運算式。

// scss
p {
$font-size: 12px;
$line-height: 30px;
font: #{$font-size}/#{$line-height};
}
// css
p {
font: 12px/30px;
}

計算顏色,採分段計算。

p {
// 計算01 + 04 = 05 , 02 + 05 = 07 , 03 + 06 = 09 => #050709
color: #010203 + #040506;
// 計算01 * 2 = 02 , 02 * 2 = 04 , 03 * 2 = 06 => #020406
color: #010203 * 2;
// 顏色值包含alpha channel(rgba 或hsla 兩種顏色值),必須擁有相等的alpha 值才能進行運算,因為算術運算不會作用於 alpha 值
color: rgba(255, 0, 0, 0.75) + rgba(0, 255, 0, 0.75);
}

加號可以連接字串。

// scss
p {
cursor: e + -resize;
}
// css
p {
cursor: e-resize;
}

加號連接會以左邊為主,左邊有引號編譯出來會有引號,若左邊沒有引號編譯出來不會有引號。

// scss
p:before {
content: 'Foo ' + Bar;
font-family: sans- + 'serif';
}
// css
p:before {
content: 'Foo Bar';
font-family: sans-serif;
}

@media 使用媒體查詢

@media 可以嵌套在 CSS 規則內,編譯時,@media 將被編譯到文件的最外層,包含嵌套的父選擇器,但這樣的使用方式會讓整個樣式非常混亂。

// scss
h1 {
font-size: 2em;
@media (min-width: 1200px) {
font-size: 3em;
}
}

// css
h1 {
font-size: 2em;
}

@media (min-width: 1200px) {
h1 {
font-size: 3em;
}
}