什麼是 SASS ?

Syntactically Awesome Stylesheets 語法很棒的樣式表
SASS是css3的擴充,增加了變數巢狀繼承函式等功能

SASS 和 SCSS 的差別

SCSS也是SASS的一種,SASS中有兩種撰寫方法,一種為SASS另一種為SCSS,SASS不使用大括弧{}
SCSS的意思是Sassy CSS

為什麼該使用 SCSS ?

日積月累的css檔案越來越不堪維護,
需求不斷改變造成css檔案越來越凌亂
相同行為卻要不斷copy/paste
往往需求一改變,就得大幅度的find/replace

SCSS提供更可靠更容易重複使用的功能,例如變數、巢狀結構、函式、繼承等方法,
當需要修改重複的style屬性時,良好的SCSS撰寫方式讓我們可以只需要更改少部分的地方即可,
SCSS容易將計有模組移至新專案中,大幅的增加css的重用性(reuse)。

  • 更清楚的style表達式
  • 更容易維護的style
  • 減少重複style(使用繼承或是mixin)
  • 減少開發專案時間
  • 容易將既有的元件搬移到其他專案
  • 可以使用運算元,也就是說可以做加減乘除的運算 <!--more-->

Style 預處理器

CSS預處理器(CSS Preprocessor),是一種構架於css之上的高級語言,可以通過腳本編譯生成CSS代碼,
其目的是為了讓CSS開發者的工作更簡單有趣,當前已經進入了較為成熟的階段,基本上新的web開發項目大
都已普遍使用。

現在最主要的選擇有

  • SASS 2007年誕生,最早也是最成熟的CSS預處理器,擁有ruby社區的支持和compass這一最強大的css框架,
    目前受LESS影響,已經進化到了全面兼容CSS的SCSS。

  • LESS 2009年出現,受SASS的影響較大,但又使用CSS的語法,讓大部分開發者和設計師更容易上手,在ruby社區
    之外支持者遠超過SASS,其缺點是比起SASS來,可編程功能不夠,不過優點是簡單和兼容CSS,反過來也影響了SASS演
    變到了SCSS的時代,著名的Twitter Bootstrap就是採用LESS做底層語言的。

  • Stylus,2010年產生,來自Node.js社區,主要用來給Node項目進行CSS預處理支持,在此社區之內有一定支持者,
    在廣泛的意義上人氣還完全不如SASS和LESS。

使用原理


安裝SCSS編譯器

  • command line
  • fire app (建議使用這個)
  • other app ( compass.app )

SCSS語法介紹

這篇文章中我們將探討

  • 巢狀
  • 變數
  • 方法
  • 繼承
  • Import

巢狀(nesting)

巢狀讓我們可以使用更直觀的寫法撰寫具有階層關係的style, 並且可以避免撰寫出重複的css。
巢狀使用縮進(indentation)的方式讓我們可以快速檢視元素之間的關係

// 範例一
// css
.infobox {
    width: 200px;
}
.infobox .message {
    border: 1px solid red;
}
.infobox .message > .title {
    color: red;
}
// scss
.infobox {
    width: 200px;
    .message {
        border: 1px solid red;
        > .title {
            color: red;
        }
    }
}
// 範例二
// & 的用法
// css 十分零散
.infobox {
    color: blue;
}
.user .infobox {
    color: gray;
}
.message {
    color: gray;
}
.message.new {
    color: red;
}
// scss 可以讓他們在一起
.infobox {
    color: blue;
    .user & {
        color: gray;
    }
}
.message {
    color: gray;
    &.new {
        color: red;
    }
}
// 範例三
// @media 我們在一起了
// css
.main {
    font-size: 15px;
}

@media screen and (max-width: 320px) {
    .main {
        font-size: 35px;
    }
}

// scss
.main {
    font-size: 15px;
    @media screen and (max-width: 320px) {
        font-size: 35px;
    }
}
// 範例四
// selectors用法
// css
em {
    color : #555;
    font-size : 14px;
    font-weight : bold;
    font-family : Georgia, Serif;
}

// scss
em {
    color: #555;
    font : {
        size : 14px;
        weight : bold;
        family : Georgia, Serif;
    }
}

變數(variables)

變數允許我們將相同的屬性值用在多個地方,要改變這些用在很多地方的值時,
我們僅需要改變這個變數的值,減少搜尋/取代的時間
變數使用開頭 :後是變數的值

// 範例一
// 基本使用方法
$primary_color: #369;
$secondary_color: #eee;

body {
    //也可以定義局部變數
    $page_width: 300px;
    background: $primary_color;
    #wrapper {
        width: $page_width;
        background: white;
        border: $secondary_color;
        h1 {
            color: $primary_color;
        }
    }
}
// 範例二
// 運算符號 Operations
// +-*/
// css
.island {
  background: #cc0000;
  width: 160px;
  margin: 32px 8px 36px 16px;
  padding: 4px;
}
// SCSS
$margin : 16px;

.island    {
    background: #cc0000;
    width: $column * 4;
    margin: $margin * 2 $margin / 2 $margin + 20 $margin;
    padding: $margin * 0.25;
}
// 範例三
// 字串相加 escaping
// 使用方法:將變數使用#{}包住
// 使用在路徑(path)表示時非常有用
// css
body {
    background-image: url(/images/dummy/d1.jpg);
}

body.banner {
    background-image: url(/images/banner.jpg)
}

// scss
$image-location : images;
$dummy-location : dummy;
body {
    background-image: url(/#{$image-location}/#{dummy-location}/d1.jpg);
    .banner {
        background-image: url(/#{$image-location}/banner.jpg);
    }
}
// 範例四
// 負數
$margin : 10px;
body {
    margin : -$margin;
}

方法(mixins)

mixins允許我們像使用function的方式重複使用css,mixin可以帶參數
Reduce massive chunks of CSS into reusable includes that you can use over and over again.
這邊不會說明@each方法(迴圈)的使用方法,在css中使用迴圈不太好吧?

// 範例一
// 基本使用方法
@mixin border-radius() {
    -webkit-border-radius: 3px;
    -moz-border-radius: 3px;
    border-radius: 3px;
}

.body {
    @include border-radius();
}
// 範例二
// 帶參數
@mixin border-radius($radius) {
    -webkit-border-radius: $radius;
    -moz-border-radius: $radius;
    border-radius: $radius;
}
// 範例三
// 參數的預設值
@mixin border-radius($radius : 3px) {
    -webkit-border-radius: $radius;
    -moz-border-radius: $radius;
    border-radius: $radius;
}
// 實際應用
// 使用background-image作為圖片時,我們時常需要撰寫許多屬性
// css
@mixin backgroundImage($val : cover) {
    background-size: $val;
    background-repeat: no-repeat;
    background-position: center;
}
.banner {
    background-size: cover;
    background-repeat: no-repeat;
    background-position: center;
}
.otehr1 {
    background-size: cover;
    background-repeat: no-repeat;
    background-position: center;
}
.otehr2 {
    background-size: cover;
    background-repeat: no-repeat;
    background-position: center;
}
// scss
@mixin background-image($background-size : cover) {
    background-size: $background-size;
    background-repeat: no-repeat;
    background-position: center;
}
.banner {
    @include background-image(cover);
}
.otehr1 {
    @include background-image(20px);
}
.otehr2 {
    @include background-image(contain);
}
// 其他更多使用方式
@mixin box-sizing($type : border-box) {
    -webkit-box-sizing: $type;
    -moz-box-sizing: $type;
    box-sizing: $type;
}

@mixin border-radius($lt) {
    -webkit-border-radius: $lt $lt $lt $lt;
    -moz-border-radius: $lt $lt $lt $lt;
    border-radius: $lt $lt $lt $lt;
}

@mixin type($font-size, $line-height, $margin) {
    font-size: $font-size;
    font-size: $font-size / 10px + rem;
    line-height: $line-height;
    margin: $margin;
}

@mixin font-size($font-size) {
    font-size: $font-size;
    font-size: $font-size / 10px + rem;
}

內建方法 : darken, lighten, etc...

第三方函式庫 > SCSS領域中的的jQuery - Compass
http://compass-style.org/

繼承(Inheritance)

繼承讓我們可以把某個元素上的屬性增加到另一個元素上,另一個元素僅需撰寫擴充的部份。

// 範例
// 網頁中時常出現圖+標題+文的格式,可以預先撰寫出一個預設樣式
// 使用者可以繼承此樣式在加以擴充,大幅減少重複的css

.article {
    @include box-sizing(border-box);
    margin: 10px;
    padding: 1em 1em;
    background-color : white;
    .title {
        @include type(20px, 1.4em, 0 0 1em);
        color: $title-color;
        font-weight: bold;
    }
    .paragraph {
        @include type(14px, 1.6em, 0 0 1.5em);
        @include border-radius(3px);
        color : $paragraph-color;
    }
    .thumbnail {
        @include background-image(cover);
        display: inline-block;
        width: 100px;
        height: 100px;
        &.left {
            float: left;
            margin-right: 10px;
        }
        &.top {

        }
    }
}

// 搜尋列表
.search-list-item {
    @extend .article;
    .title {
        @include font-size(16px);
        color: #389;
    }
    .paragraph {
        @include font-size(13px);
    }
    // 針對自己需要的部份增加
    .time {
        color: #888;
        @include type(13px, 1.3em, 0);
    }
}

// 產品列表
.product-list-item {
    @extend .article;
    float: left;
    width: 300px;

    // media query can be nexted
    @media screen and (max-width: 480px) {
        width: 100%;
    }

    .title {
        @include font-size(16px);
    }
    .paragraph {
        @include font-size(13px);
    }
    .thumbnail {
        width: 100%;
        height: 160px;
        margin-bottom: 15px;
    }
    // 針對自己需要的部份增加
    .price {
        @include type(14px, 1.3em, 0);
        color: #389;
        font-weight: bold;
    }
}

Import (_partials)

scss允許我們將sccs分別撰寫至不同的.scss檔案中,最後使用import的方式將這些檔案組裝起來

好處:

  • 可以將全域變數、方法儲存在global.scss中,方便查閱及更改,甚至可以搬遷至其他專案使用
  • 將不同頁面的style撰寫至不同的.scss檔案中,最後由主要的style.scss匯入進來,減少過去所有css撰寫在 同一個檔案難以維護的缺點

注意事項

SCSS 開發原則:禁用 @import 'compass';
http://ruby-china.org/topics/10699

參考資料