SASS教學 +SCSS:CSS 再進化,掌握語法攻略!

0
655
sass 教學
sass 教學

這幾天摸索了 SASS+SCSS 的寫法,發現有許多的 GitHub 專案,使用它進行開發。

自己進行幾個專案後,編寫速度確實有提升,於是整理出這篇 SASS+SCSS 教學,從 SASS+SCSS 介紹 → 安裝+執行 → 語法 SASS教學 ,進行文章編寫。

不敢說可以從入門到進階,但對 SASS 主觀念的掌握,應該是沒問題的,那我們開始囉 😀 😀


subject-1

1. SASS+SCSS 介紹

SASS 是一個成熟且穩定的 CSS 預處理器,除了把普通的 CSS 語法強化,它還使用了 SassScript 增加了許多功能,如:變量、嵌套、混合、導入等 .. 功能,在一般專案的編寫或是中大型的專案上,都可以編寫的更加快速。

SASS 會編譯(compiled)程式碼,轉成一般 CSS 形式,讓瀏覽器可以解讀輸出,把頁面呈現出來。

主要包含兩種寫法:分別是舊版的 SASS(縮排語法,副檔名.sass,使用縮排來區分程式碼塊,與 Haml 類似)和新版的 SCSS(塊語法,副檔名.scss,使用和 CSS 相同方式,用大括號分開)。

SCSS 的原型是 SASS,所以都通稱 SASS 也沒問題,只是寫法有些許不同,我們先來看一下:

/** 一般 css 寫法 **/
.nav{
    background: #ccc;
}
.nav li {
    display: inline-block;
}
.nav li a{
    display: block;
    padding: 15px;
    text-decoration: none;
    color: #000;
}
.nav li img{
    width: 100%;
}

SASS寫法:採用「 縮進語法(TAB)」的方式,去除了一般 CSS 的括號、分號等 .. 加快編寫流程,有一部分的人喜歡這樣的編寫方式而採用,如下:

/** sass寫法 **/
.nav
    background: #ccc
    li
        display: inline-block
        a
            display: block
            padding: 15px
            text-decoration: none
            color: #000
        img
            width: 100%

SCSS寫法:採用「 塊語法(Block)」,一般從 CSS 轉為 SCSS 開發比較無痛,保留了括號、分號等 .. 元素,相對於上面的 SASS 是比較新的編寫方式,學習成本比較低,是目前主流的方式,如下:

/** scss寫法 **/
.nav{
    background: #ccc;
    li {
        display: inline;
        a {
            display: block;
            padding: 15px;
            text-decoration: none;
            color: #000;
        }
        img {
            width: 100%;
        }
    }
}

看完上面的程式碼,會發現 SASS 可以協助解決編寫 CSS 常遇到的幾個問題,如:「 重複編寫 」、「 後續維護 」、「 漏寫問題 」等問題 ..,然後加快開發流程,如下:

  1. 父選擇器,重複編寫:如要擴充頁面樣式,就會不斷的加上 .nav li .. 等父級 class 名稱,比較費工!
  2. 屬性樣式,重複編寫:常會看到許多 CSS 屬性,是許多區塊都需要用到,在 SASS 沒出來前,每個區塊都需特別寫一遍,現在直接引用即可。
  3. 後續維護:若哪天需要把 .nav 這個 class 名稱更換,就需全部替換,比較麻煩。
  4. 漏寫問題:SASS / SCSS 有條理的節省了許多代碼編寫,降低漏寫的Bug。

若想了解更多 SASS & SCSS 差異,也可以 看這篇 stack oveflow 的討論:)


subject-2

2. 安裝+執行

安裝+執行 SASS 的方式有滿多種,有使用第三方應用程式的,也有直接安裝在本機上的,這邊會建議直接安裝在本機上,比較一勞永逸,這邊列出幾種安裝方式,如下:

SASS 安裝

1. 使用 Node.js 安裝 $ npm install -g sass

2. 使用 Ruby 安裝 $ gem install compass

3. 使用 Brew 安裝(Mac專用)$ brew install sass

指令執行完成,基本上就安裝好了,若想測試是否安裝成功,可以輸入 $sass -v 看是否有顯示 SASS 版本號,若有的話代表安裝完成 😆 😆

SASS 執行

首先在專案資料夾下,生成 index.html 和兩個資料夾 css、sass ,然後在 sass 下面新增一個 style.scss,這支檔是我們開發,主要編寫樣式的檔案。

sass 範例檔案
sass 範例檔案

我們現在要試著把 sass 資料夾裡的 style.scss ,編譯成瀏覽器看的懂的 .css 副檔名型式。

所以下指令把 style.scss 檔案轉譯生成 style.css,並放置在 css 資料夾裡,如下:

$ sass sass/style.scss:css/style.css

如果順利的話,應該會看到「 css 」檔案夾裡,新增了兩個檔案,分別是「 style.css 」和「 style.css.map 」,這邊比較要留意的是 style.css(瀏覽器主要解讀這隻檔)。

sass 轉譯成 css
sass 轉譯成 css
  1. 需留意「 當前路徑 」,這會影響到 style.scss 檔案編譯生成 style.css 的路徑,若不對會報錯唷 😯 😯
  2. 在 index.html 裡面,記得引入 style.css 檔案( style.scss 不需引入 ),才會有樣式出現唷!

若持續有樣式需新增,每次一編寫完 style.scss 就得執行一次 $ sass sass/style.scss:css/style.css 指令,才能在瀏覽器上看到變化,相信一定會很想撞牆 🙁 🙁

所以這時可以改下另一個指令(加上 --watch 參數,若原有的 style.css / style.css.map 已存在,會自動覆蓋,不存在的話會自動生成新的),如下:

$ sass --watch sass/style.scss:css/style.css

執行後,會發現 sass 已經開始在監聽 style.scss ,若這隻檔案有修改,style.css 變會即時的進行編譯,給瀏覽器做使用,如下影片:

在開發過程中,一個專案可能不只有一個樣式檔,假如有多個檔案需同時進行監聽,這邊提供幾個方式給大家:

1. 重複執行:看有幾個檔案需監聽,就輸入幾次。

$ sass --watch path/to/filename.scss:path/filename.css

2. 一次執行:看有幾個檔案需監聽,一次下指令。

$ sass --watch path/filename1.scss:path/filename1.css path/filename2.scss:path/filename2.css path/filename3.scss:path/filename3.css

3. 指定目錄下全部監聽:監聽 sass 目錄下的 sass/scss 檔案到指定的 css 目錄下(下面指令為兩個資料夾在同一層)

$ sass --watch sass:css

4. 當前目錄下全數監聽,並直接生成 css 檔案。

$ sass --watch .

到了這一步,若順利的話,相信你也學會,如何在編寫 sass/scss 檔案時,指定的 css 檔案可以同步的進行編譯,並讓瀏覽器能夠順利的出現畫面。

個人覺的 sass 學習比較麻煩的就是安裝+執行這個章節,後面就是語法部分,語法就相對簡單明瞭了,原來就有 css 開發經驗的捧有們,相信也可以很快就入手的 😀 😀

接下來,我們開始前進到語法部分囉:)


subject-3

3. 嵌套

SASS 提供 CSS 語法擴展,如:嵌套功能( Nested Rules ),主要是解決 CSS 編寫過程中,父元素重複編寫問題,可以縮短開發流程、方便後續維護、樣式模組化等.. 優點 🙂 🙂

這是容易入門 SASS教學 的第一步,直接上代碼,我們使用 SASS 編寫樣式,並對比編譯後的 CSS ,如下:

/** 編譯前( sass 語法 ) **/
#main {
    width: 200px;
    height: 100px;
    background: #ddb92a;

    .greenbox{
        width: 100px;
        height: 50px;
        background: green;
        p, a {
            font-size: 20px;
        }
    }
}
/** 編譯後( 轉為 CSS 語法輸出 ) **/
#main {
    width: 200px;
    height: 100px;
    background: #ddb92a;
}
#main .greenbox{
    width: 100px;
    height: 50px;
    background: green;
}
#main .greenbox p, #main .greenbox a{
    font-size: 20px;
}

除此之外,常用的屬性也可以進行 CSS「 嵌套屬性 」,比如: font-familyfont-sizefont-weight,會發現 font 多次出現。

還有常見的 background 系列,比如:background-colorbackground-positionbackground-sizebackground-image,都可以用嵌套功能,來節省開發時間唷,這邊上代碼,如下 🙂 🙂

/** 編譯前( sass語法 ) **/
.main {
    font: {
        family: Helvetica, sans-serif;
        size: 15em;
        weight: bold;
    }
}

/** 編譯後( 轉為 CSS 語法輸出 ) **/
.main {
    font-family: Helvetica, sans-serif;
    font-size: 15em;
    font-weight: bold;
}

到目前,對嵌套功能應該有初步認識了,若之前有看過別人寫的 SASS / SCSS 檔,應該會有種似曾相似的感覺吧 😉 😉

理解了它,接下來我們繼續看 SASS 還有什麼特別的地方,可以讓我們學習的 ..


subject-4

4. 引用父選擇器 &

如果想在嵌套狀態下,取得外層的父選擇器,那可以使用「 & 」,它會直接抓父選擇器給你用。

常會把它用在,如 CSS 元件狀態: :hover:focus:hover:link:visited 等 ..,或是 :before:after ,這邊上個代碼,如下:

/** 編譯前( sass語法 ) **/
#main {
    display: block;
    a {
        color: #d0b95b;
        &:hover, &:active, &:focus {
            color: #a08106;
            outline: none;
            text-decoration: none !important;
        }
    }
}

/** 編譯後( 轉為 CSS 語法輸出 ) **/
#main {
    display: block;
}
#main a {
    color: #d0b95b;
}
#main a:hover, #main a:active, #main a:focus {
    color: #a08106;
    outline: none;
    text-decoration: none !important;
}

還有另一種用法,也常常看到,如下:

/** 編譯前( sass語法 ) **/
#main{
    &.color-2{
        background: red;
        &:before{
            border: 1px solid #ccc;
        }
    }
    &.color-3{
        background: yellow;
        &:before{
            border: 1px solid blue;
        }
    }
}

/** 編譯後( 轉為 CSS 語法輸出 ) **/
#main.color-2 {
    background: red; 
}
#main.color-2:before {
    border: 1px solid #ccc; 
}
#main.color-3 {
    background: yellow; 
}
#main.color-3:before {
    border: 1px solid blue; 
}

能抓到父選擇器,是不是開發起來也方便多了呢?

一開始看到別人編寫的 SASS 時,覺得「 & 」的寫法滿酷的,後來才懂 .. 原來是這樣運作呀 😀 😀


subject-5

5. 變量

在我們實際編寫 CSS 的過程中,常會遇到多次相同的顏色、字型、字體大小等 .. 重複出現。

重複出現是好事,因為只要複製+貼上就好了 .. 但假如遇到哪天設計師 / 客戶,需要修改就 ..(因為全都需要更改 😯 😯 )

所以 SASS 可以協助我們解決這問題,就如同 JS 變量邏輯一樣,只需改最源頭的變量即可,其他所有引用該變量的地方,值都會自動更改。

SASS 中使用 $ 進行變量聲明,支持 7 種主要數據類型:

  • 數字(如:1, 1.5, 20px
  • 字符串,帶引號和不帶引號(如:"foo", 'foo', foo
  • 顏色(如:red, #28b0b4, rgba(0, 0, 0, 0.5)
  • 布爾值(如: true, false
  • 空值(如: null
  • 值列表(list),用空格或逗號分開(如:2em 1em 0 1emHelvetica, Arial
  • maps:從一個值映射到另一個(如:(key1: value1, key2: value2)

這邊來對比一下,使用 SASS 開發的編譯前( SASS 語法 ) & 編譯後( 轉為 CSS 語法輸出 )的程式碼,如下:

/** 編譯前( sass 語法 ) **/
$bnr-font: Helvetica, sans-serif;
$bnr-color: #494947;

.banner1 p{
    font-family: $bnr-font;
    color: $bnr-color;
    padding: 10px 15px;
    letter-spacing: 0.2em;
}
.banner2 p{
    font-family: $bnr-font;
    color: $bnr-color;
    margin: 15px;
}
/** 編譯後( 轉為 CSS 語法輸出 ) **/
.banner1 p{
    font-family: Helvetica, sans-serif;
    color: #494947;
    padding: 10px 15px;
    letter-spacing: 0.2em;
}
.banner2 p{
    font-family: Helvetica, sans-serif;
    color: #494947;
    margin: 15px;
}

如此一來,當哪天收到需要更改某通用按鈕顏色、通用字體字型 .. ,就可以直接更改變量即可,是不是很方便 😆 😆


subject-6

6. 引入

SASS 擴展了 CSS 的 @import 功能,允許在文件內導入其他的 SASS 或 SCSS 子文件。

在文件進行編譯後,被導入的 SASS 或 SCSS 子文件,會全部合併到同一個 CSS 文件,然後呈現出來。

常見的 .sass.scss 導入

這邊展示一下基本用法,我們把 _reset.scss 導入到 main.scss 中,直接上代碼:

/** 編譯前( sass 語法 ) **/
/** _reset.scss **/
html, body, ul, ol, a {
    margin:  0;
    padding: 0;
}

/** main.scss **/
@import 'reset';
body {
    background: #a08106;
    font-size: 16px;
}
/** 編譯後( 轉為 CSS 語法輸出 ) **/
html, body, ul, ol, a {
    margin:  0;
    padding: 0;
}
body {
    background: #a08106;
    font-size: 16px;
}

小提醒:若有多個文件需匯入,可同時使用多個 @import 引用文件,如下圖   😛 😛

bootstrap 多個文件引入
bootstrap.scss 多個文件引入

監聽父文件即可

編寫代碼過程中,可以把不同樣式區塊的 SASS 或 SCSS 代碼,拆開成不同獨立的文件,然後使用 @import 把各片段文件,統整匯入到同一支 .sass.scss 文件中,並監聽這一支文件即可 😛 😛

在文件進行監聽時,所有 @import 進來的 .sass.scss 子文件,也同時被監聽,所以當子文件有修改,父文件編譯出的 .css 也會自動更新。

使用下劃線,SASS 編譯自動忽略

若有片段文件不需 SASS 編譯出新的 CSS 文件,可在文件開頭添加一個下劃線,在編譯過程中,系統就會忽略它,而只對開頭無下劃線的文件,進行新的 CSS 文件生成。

上述的範例說明

看一下另一個範例,下面是 bootstrap 的目錄文件:

sass 的 @import 功能
左圖:目錄結構  。  右圖: bootstrap.scss 文件
  1. 把多個 scss 文件,使用 @import 添加到  bootstrap.scss 中。之後只需監聽 --watch bootstrap.scss 這一支文件即可,假如內部 @import 的文件有變更,都會在 bootstrap.css 自動更新。
  2. bootstrap.scss 文件內的 @import 檔案,不需要加下劃線。
  3. 開頭有下劃線的文件,在執行 sass 指令時,不會生成新的 css 文件,系統會自動忽略。
  4. @import scss 片段文件,不用加上副檔名也可以,系統會自動尋找同名的副檔名 .scss.sass 文件,並依序導入。

一般 CSS @import 功能

@import 默認情況,會預設導入同名的 .sass.scss 文件,但在以下情況下,僅當成一般的 CSS @import 語句,不會導入任何的 SASS 文件,如下:

  • 如果文件的副檔名是 .css@import "foo.css";
  • 文件名以 http:// 開始 :@import "http://foo.com/bar";
  • 文件名是 url()@import url(foo);
  • @import 中包含媒體查詢(media queries)

subject-7

7. 混合

若是有重複的代碼,會不斷使用到,就可用混合指令(Mixin Directives),直接把樣式封裝成一個類名稱,就可以重複調用,如下:

/** 編譯前( sass 語法 ) **/
/** 定義 mixin 指令 **/
@mixin font-main {
    font: {
      family: Arial;
      size: 16px;
      weight: 100;
    }
    color: #000;
}

/** 引用 mixin **/
.box p {
    @include font-main;
}
/** 編譯後( 轉為 CSS 語法輸出 ) **/
.box p {
  font-family: Arial;
  font-size: 16px;
  font-weight: 100;
  color: #000; 
}
  • 使用 @mixin 定義一個「 混合 」
  • 使用 @include 引用一個「 混合 」
  • 可同時引用多個「 混合 」

使用參數功能

使用「 混合 」功能,有設置參數功能( 可設定默認值 ),讓整體功能變更彈性,有點像函數的傳入參數,如下:

/** 編譯前( sass語法 ) **/
/** 定義 mixin 指令 **/
@mixin border-set($color, $width, $style: solid) {
    border: {
        color: $color;
        width: $width;
        style: $style;
    }
}
@mixin background-set($color, $image, $repeat) {
    background: {
        color: $color;
        image: url($image);
        repeat: $repeat;
    }
}

/** 引用 mixin **/
.box div {
    @include border-set(red, 2px);
    @include background-set(green, "../img_tree.png", 'no-repeat');
    letter-spacing: 0.5em;
}
/** 編譯後( 轉為 CSS 語法輸出 ) **/
.box div {
  border-color: red;
  border-width: 2px;
  border-style: solid;
  background-color: green;
  background-image: url("../img_tree.png");
  background-repeat: "no-repeat";
  letter-spacing: 0.5em; 
}

subject-8

8. 繼承

「 繼承 」@extend 是一個滿實用的功能,若想讓多個 class 使用相同樣式,就可使用 @extend 直接繼承過來,減少重複編寫的時間,如下:

/** 編譯前( sass語法 ) **/
%msg-style {
    display: block;
    flex-wrap: wrap;
    background: #d9d9d8;
    color: #000;
}

.msg {
    @extend %msg-style;
}

.msg-success {
    @extend %msg-style;
    background: #34fc6d;
}

.msg-error {
    @extend %msg-style;
    background: #fc253e;
}
/** 編譯後( 轉為 CSS 語法輸出 ) **/
.msg, .msg-success, .msg-error {
  display: block;
  flex-wrap: wrap;
  background: #d9d9d8;
  color: #000; 
}

.msg-success {
  background: #34fc6d; 
}

.msg-error {
  background: #fc253e; 
}
  • 使用站位選擇器 % ,定義一個樣式,被定義的類,它將不會被編譯出來。
  • 若沒有標註 % 的類,也可以使用 @extend 引入,但定義的類會被編譯出來。
  • 有使用 @extend 的類,會被系統編譯整合,使用共用樣式。

多重擴展,可引入多個選擇器

同一個選擇器,可以使用 @extend擴展多個選擇器,這代表它繼承了擴展選擇器的樣式,如下:

/** 編譯前( sass語法 ) **/
.error {
    background-color: #fa945c;
}

.notice {
    font-size: 16px;
    font-family: sans-serif;
    font-color: #000;
}

.seriousError {
    @extend .error;
    @extend .notice;
    background-color: #ff1b1b;
}
/** 編譯後( 轉為 CSS 語法輸出 ) **/
.error, .seriousError {
  background-color: #fa945c; 
}

.notice, .seriousError {
  font-size: 16px;
  font-family: sans-serif;
  font-color: #000; 
}

.seriousError {
  background-color: #ff1b1b; 
}

上面幾個狀況,應該是比較常見的 @extend 功能,應該滿足夠使用了,若想了解更多,可以直接參考 SASS 官方


subject-9

9. 操作符

SassScript 支持對數字的運算,如:(加法 +、減法 +、乘法 *、除法 /、取模 % 等 ..),來看一下代碼,如下:

/** 編譯前( sass 語法 ) **/
div a {
    $width: 500px;
    width: $width/2;             // 使用變量,和 / 
    font: 16px/10px;             // 原生CSS,不作為除法
    height: (250px/2);           // 使用了(), 和 /
    margin-left: 10px + 8px/2px; // 使用了 +, 和 /
}
/** 編譯後( 轉為 CSS 語法輸出 ) **/
div a {
  width: 250px;
  font: 16px/10px;
  height: 125px;
  margin-left: 14px; 
}

簡單來說,就是增加了運算功能,有需要也可進行使用。

這邊也有另一個範例,如下:

/** 編譯前( sass語法 ) **/
.container { width: 100%; }

article[role="main"] {
  float: left;
  width: 700px / 960px * 100%;
}

aside[role="complementary"] {
  float: right;
  width: 400px / 960px * 100%;
}
/** 編譯後( 轉為 CSS 語法輸出 ) **/
.container {
  width: 100%; 
}

article[role="main"] {
  float: left;
  width: 72.9166666667%; 
}

aside[role="complementary"] {
  float: right;
  width: 41.6666666667%; 
}

subject-10

10. 結論

如果能看到這邊,首先給自己掌聲!相信對 SASS教學 ,也有程度的認識了!

接著,可以找個小案子,來自己練習,你會發現,CSS 結合了 JS 特性,開發起來會變得更加快速(省了很多代碼 😀 😀 )

SASS 在入門安裝+下指令時,會有些要適應,但這邊搞定後,會發現後面語法觀念,其實很容易上手,優化了傳統 CSS 開發上的許多不變。

希望這篇 SASS教學 文,有幫助到需要的捧有們,我們下篇文章見 🙂 🙂

 

資料參考(若沒附上的,再麻煩提醒我,我在加上去,感謝~):

Sass-Basics

Github:Sass makes CSS fun! 

Sass-Guidelines

莊小犬:我是站長小犬,長期關注程式技術的大小事:)

發表迴響