Sass帶來的變革_sass, scss 教程_w3cplus - Google Chrome

Sass帶來的變革

接觸Sass差很少有一個年頭了,在這一年來的時間中,也花了很多心思在Sass的學習上。同時也讓本身喜歡上了Sass,目前在本身的私人項目中,我一直都在使用Sass作爲前端開發,用來處理CSS。同時今年本身建立了下Sass中國網站來作Sass相關的技術分享。其實,在W3cplus站點上,已經發布了近一百篇有關於Sass方面的教程(教程有本身的學習心得、有譯文,也有其餘同窗的使用經驗分享)。也自認本身是Sass在中國的推廣者,其實我也更想作爲Sass在中國的佈道者,讓更多的人瞭解他,學習他,使用他。javascript

那麼回到話題的正題中來,今天要說的是Sass帶來的變革,其實標題有點浮誇,也能夠當其是標題黨吧。他是出自於本身在兄弟公司作分享的一份PPT。由於時常能碰到同窗在問:php

  • Sass是什麼?
  • 怎麼學習Sass?
  • 如何在項目中使用Sass?

等等一系列問題,其實在前面的教程中或多或少都有介紹,那麼今天藉此機會將前面所整理的教程、譯文作一個系統的概括吧,讓有須要的同窗能更好的學習和使用Sass。css

Sass是什麼?

Sass是"Syntactically Awesome StyleSheets"的簡稱。那麼他是什麼?其實沒有必要太過於糾結,只要知道他是「CSS預處理器」中的一種便可,簡單點說,Sass就是「CSS預處理器」,你能夠稱其是工具或者是語言。若是你實在想知道他是什麼?能夠看Sass官網上的一段描述。html

Sass is an extension of CSS that adds power and elegance to the basic language. It allows you to use variables, nested rules, mixins, inline imports, and more, all with a fully CSS-compatible syntax. Sass helps keep large stylesheets well-organized, and get small stylesheets up and running quickly, particularly with the help of the Compass style library.前端

爲何選擇Sass?

與Sass齊名的CSS預處理器還有LESSStylus等。這也引出一個激烈的討論,Sass和LESS哪家技術強。並且這個討論在不少論壇和平臺都有出現過:好比2012年5月份Chris Coyier發表的《Sass vs LESS》一文,記得看文章後面的評論,由於評論的內容更精彩。java

對於我我的爲何從新選擇使用Sass,緣由很是的簡單,功能上來講他們都相似,也沒有哪家比哪家強一說,但對於初學者,學習任何一門新技術,除了官網文檔以外,但願有其餘的教程或者資料,從這一點上來講,Sass相關的資料就很是的多。除此以外,使用Sass寫的案例與框架也多。這就是我選擇他的緣由。若是你想先簡單的瞭解Sass、LESS和Stylus有哪些不同,再作出選擇的話,能夠看一篇2013年我在《程序員》雜誌上發表的一篇文章《CSS預處理器——Sass、LESS和Stylus實踐【未刪減版】》。node

擴展閱讀

Sass功能與特性

Sass如今更新到3.4.7版本(寫這篇文章時最新版本),其實Sass有不少功能和特性是CSS沒法匹敵的,好比:變量、繼承、混合宏、佔位符、邏輯判斷、函數、@at-root、列表和map等等。這些都是Sass的基本功能,能夠說掌握了這些功能,配合你本身的創造力,可使用Sass作更多有意義的事情。git

擴展閱讀

Sass學習路線

學習Sass仍是具備必定的成本的。這樣說吧,他和CSS基本相似,說得難聽一點,你把你的.css更換成.scss文件,這就是現成的Sass。但要真正懂Sass仍是須要必定的時間的。在這裏,我來聊聊我是怎麼樣學習Sass的,或者說我學習Sass的一個路線是什麼樣的。程序員

我將學習Sass分爲三個階段。github

初級階段

初級階段就是一個入門的過程,知道怎麼使用Sass。在這個過程當中主要包括如下幾個部分:

  • 運行Sass環境
  • Sass安裝
  • Sass語法
  • Sass編譯
  • Sass調試

運行Sass的環境

Sass是基於Ruby開發的,因此要運行Sass都須要一個Ruby環境。但並非說你要懂得Ruby,你只須要在你的電腦中安裝一個Ruby環境便可。若是你使用的是Mac電腦,那麼就不須要安裝,若是你使用的是Win系統,那麼須要先在電腦中安裝Ruby。也正是由於這個緣由,不少同窗以爲Sass要依賴於Ruby環境,而放棄使用Sass。

至於如何安裝Ruby,就不作過多闡述,由於如今的應用軟件安裝都是很是簡單的,一路下一步便可。

擴展閱讀

Sass安裝

對於Sass安裝來講是件很是簡單的事情,只須要在你的命令終端輸入一行命令便可:

gem install sass

提醒一下,在使用Mac的同窗,可能須要在上面的命令加上sudo,才能正常安裝:

sudo gem install sass 

若是你是一位Sass發燒友,你也能夠經過--pre參數來安裝Sass開發版本,領略Sass的一些最新功能與特性:

gem install sass --pre

不過在天朝每每上面的命令讓你沒法正常實現安裝,若是你碰到這樣的事情,那麼須要特殊去處理。能夠到Rubygems網站上下載Sass安裝包,而後在命令終端輸入:

gem install <把下載的安裝包拖到這裏>

直接回車(Enter)便可安裝成功。若是你不確認你的Sass是否安裝成功,只須要輸入命令:

sass -v

看到版本號就表示安裝成功。

Sass語法

Sass語法規則有兩種,一種是經過tab鍵控制縮進的語法規則(縮進要求很是嚴格),這種語法對於熟悉Ruby的同窗來講會很是的方便和喜歡。這種語法的Sass文件是以.sass後綴命名。另外一種語法是SCSS,這是Sass的新的語法規則,他的外觀和CSS的如出一轍,文件後綴是.scss。以下所示:

//Sass語法
$width: 200px
.box
    width: $width

//SCSS語法
$width: 200px;
.box {
    width: $width;
}

來看個示意圖:

Sass語法

正由於如此,有很多同窗,使用的是Sass新的語法規則,而文件後綴依舊是.sass,這也就形成血案了,編譯時說編譯不出來。因此在此特別提醒新同窗:.sass只能使用Sass老語法規則(縮進規則),.scss使用的是Sass新語法規則(相似CSS語法)。

上面只演示了最基礎的語法規則,其實在定義混合宏,調用混合宏,他們都略有不一樣。對於前端人員,我的更建議使用SCSS語法風格,比較適應,也不會那麼容易出錯。

Sass編譯

衆所周知,到目前爲止,各瀏覽器是沒法直接解析.scss或者.sass文件。換句話說,在Web實際掉用當中,仍是須要調用.css文件。這個問題也困擾了不少初學者,經常有人會問,使用Sass進行開發,那麼是否是直接經過<link>引用.scss.sass文件呢?那麼這裏告訴你們,在項目中仍是引用.css文件,Sass只不過是作爲一個預處理工具,提早幫你作事情,只有你須要的時候,他才能功效。

這樣一來,在Sass開發以後,要使用寫好的東西,讓Web頁面能調用,就得通過一個過程,這個過程就是Sass編譯過程。Sass的編譯有多種方法:

命令編譯

若是你喜歡操縱你的命令終端,那麼能夠直接經過命令終端來對Sass進行編譯,只須要命令終端輸入:

sass <要編譯的Sass文件路徑>/style.scss:<要輸出CSS文件路徑>/style.css

這是對一個單文件進行編譯,若是想對整個項目裏全部Sass文件編譯成CSS文件,能夠這樣操做:

sass sass/:css/

上面的命令表示將項目中sass目錄中全部.scss(.sass)文件編譯成.css文件,而且這些CSS文件都放在css目錄當中。

在實際編譯過程當中,你會發現上面的命令,只能一次性編譯。每次修改保存.scss文件以後,都得得新執行一次這樣的命令,如此操做太麻煩,其實還有一種方法,就是在編譯Sass時,開啓watch功能,這樣只要你的代碼進行任何修改,他都能自動監測到代碼的變化,而且給你直接編譯過來。

sass --watch <要編譯的Sass文件路徑>/style.scss:<要輸出CSS文件路徑>/style.css

命令編譯就是這麼的簡單。固然,使用sass命令編譯時,能夠帶不少參數。

Sass編譯命令參數

GUI編譯

若是平時工做中不太喜歡使用命令終端的同窗,能夠考慮使用GUI界面工具來對Sass進行編譯。固然不一樣的GUI工具操做方法略有不一樣。在此也不一一對編譯的界面工具作詳細的介紹。對於GUI界面編譯工具,目前較爲流行的主要有:

自動化配置編譯Sass

喜歡自動化研究的同窗,應該都知道GruntGulp這兩個東東。若是您正在使用其中的任何一種,那麼你也能夠經過他們來配置,也能夠完成Sass的編譯。

//Grunt
module.exports = function(grunt) {
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        sass: {
            dist: {
                files: {
                    'style/style.css' : 'sass/style.scss'
                }
            }
        },
        watch: {
            css: {
                files: '**/*.scss',
                tasks: ['sass']
            }
        }
    });
    grunt.loadNpmTasks('grunt-contrib-sass');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.registerTask('default',['watch']);
}

//Gulp
var gulp = require('gulp');
var sass = require('gulp-sass');

gulp.task('sass', function () {
    gulp.src('./scss/*.scss')
        .pipe(sass())
        .pipe(gulp.dest('./css'));
});

gulp.task('watch', function() {
    gulp.watch('scss/*.scss', ['sass']);
});

gulp.task('default', ['sass','watch']);
擴展閱讀

Sass調試

Sass調試

Sass調試一直以來都是一件頭痛的事情,使用Sass的同窗都但願能在瀏覽器中直接調試Sass文件,能找到對應的行數。值得慶幸的是,如今要實現並非一件難事了,只要你的瀏覽器支持"Sourcemap"功能便可。早一點的版本,須要在編譯的時候添加--sourcemap參數:

sass --watch --scss --sourcemap style.scss:style.css

在3.3版本之上(我測試使用的版本是3.4.7),不須要添加這個參數也能夠:

sass --watch style.scss:style.css

在命令終端,你將看到一個信息:

>>> Change detected to: style.scss
  write style.css
  write style.css.map

這時你就能夠像前面展現的gif圖同樣,調試你的Sass代碼。

擴展閱讀

若是掌握了上面提到的知識,我想你已具有Sass的初級水平。你會安裝Sass、知道Sass語法、會編寫Sass代碼,也能編譯Sass,還能調試Sass代碼。但這僅僅是Sass的基礎知識。若是還要深刻,仍是須要花很多時間去學習與實戰的。

中級階段

具備Sass初級階段水平以後,你對Sass也有了基本的瞭解,也能用Sass去作一些簡單的事情。若是要深刻仍是要繼續往下學習的。接下來向你們簡單介紹有關於Sass方面更有興趣的東東。

Sass的基本功能

Sass功能和特性有不少,要把全部東西介紹完,我想徹底能夠寫一本書了,那麼在這裏主要向你們介紹一些Sass最基本、最經常使用的特性:

  • 變量
  • 混合宏@mixin
  • 繼承
  • 佔位符%placeholder
  • 嵌套
  • 運算符
  • 選擇符&
  • 列表$list
  • 函數@function
  • map
  • 控制命令
  • @at-root
變量

先來看一張圖

Sass變量

上圖很是清楚告訴了你們,Sass的變量包括三個部分:

  • 聲明變量的符號$
  • 變量名稱
  • 賦予變量的值

定義變量,就能夠在代碼中調用了:

//SCSS
$color: orange !default;

.block {
  color: $color;
}

//CSS
.block {
  color: orange;
}

說到變量,大多數人都會想到全局變量和局部變量。早期的Sass是不具備這樣的概念,但新版本中3.4以後有點這方面的意思了。來看一個簡單的示例:

//SCSS
$color: orange !default;

.block {
  color: $color;
}

em {
  $color: red;

  a {
    color: $color;
  }
}

span {
  color: $color;
}
//CSS
.block {
  color: orange;
}

em a {
  color: red;
}

span {
  color: orange;
}

上面的示例演示能夠得知,在元素內部定義的變量不會影響其餘元素。如此能夠簡單的理解成,定義在元素外面的變量,好比$color:orange !default;是一個全局變量,而定義在元素內部的變量,好比$color:red;是一個局部變量。除此以外,Sass如今還提供一個!global參數:

//SCSS
$color: orange !global;

.block {
  color: $color;
}

em {
  $color: red;

  a {
    color: $color;
  }
}

span {
  color: $color;
}
//CSS
.block {
  color: orange;
}

em a {
  color: red;
}

span {
  color: orange;
}

!global從名稱上看是一個全局變量,但和全面彷佛沒有太大區別,不過咱們來換過一種測試效果,將!gobal放在內部,其也將會影響全局:

//SCSS
$color: orange !global;

.block {
  color: $color;
}

em {
  $color: red !global;

  a {
    $color: lime;
    color: $color;
  }
}

span {
  $color: yellow;
  color: $color;
}
.i {
  color: $color;
}
//CSS
.block {
  color: orange;
}

em a {
  color: lime;
}

span {
  color: yellow;
}

.i {
  color: red;
}

除非元素自身重置變量,才能覆蓋!global的變量。

擴展閱讀
混合宏@mixin

Sass中的混合宏是經過@mixin來聲明,而後經過@include來引用。混合宏主要功能就是將一些共用功能樣式代碼合併在一塊兒。好比:

@mixin box-shadow($shadow...) {
  @if length($shadow) >= 1 {
    box-shadow:$shadow;
  } @else{
    $shadow:0 0 4px rgba(0,0,0,.3);
    box-shadow:$shadow;
  }
}

引用混合宏是經過@include:

.block { @include box-shadow;
}

.hidden {
  @include box-shadow(inset 0 0 1px rgba(red,.5),0 0 2px rgba(red,.25));
}

編譯出來的CSS:

.block { box-shadow: 0 0 4px rgba(0, 0, 0, 0.3); }

.hidden { box-shadow: inset 0 0 1px rgba(255, 0, 0, 0.5), 0 0 2px rgba(255, 0, 0, 0.25); }

這樣可能還看不出其特點,將上面的示例稍做變化:

//SCSS
.block { @include box-shadow;
}

.hidden {
  @include box-shadow(inset 0 0 1px rgba(red,.5),0 0 2px rgba(red,.25));
}

.header {
  @include box-shadow;

  h2 {
    @include box-shadow(1px 1px 2px rgba(green,.3),inset 0 0 2px rgba(green,.3));
  }
}
//CSS
.block { box-shadow: 0 0 4px rgba(0, 0, 0, 0.3);
}

.hidden {
  box-shadow: inset 0 0 1px rgba(255, 0, 0, 0.5), 0 0 2px rgba(255, 0, 0, 0.25);
}

.header {
  box-shadow: 0 0 4px rgba(0, 0, 0, 0.3);
}
.header h2 {
  box-shadow: 1px 1px 2px rgba(0, 128, 0, 0.3), inset 0 0 2px rgba(0, 128, 0, 0.3);
}

編譯出來的CSS代碼,你們不難發現,其中.block.header是樣式代碼是同樣的,但Sass編譯出來並無將其合併在一塊兒:

.block { box-shadow: 0 0 4px rgba(0, 0, 0, 0.3); }

...

.header { box-shadow: 0 0 4px rgba(0, 0, 0, 0.3); }

這其實也是Sass中混合宏@mixin最不盡人意之處,其最大特徵就是能夠爲其傳參數。那麼你們須要記住一點,若是你的功用代碼塊,須要傳參數,那麼這個功能塊應該使用Sass的混合宏@mixin來定義。

擴展閱讀
繼承

繼承對於CSS來講並非陌生的事情,先來看張圖:

Sass繼承

圖中代碼顯示.col-sub .block li,.col-extra .block li繼承了.item-list ul li選擇器的padding:0;ul li選擇器中的list-style:none outside none;以及*選擇器中的box-sizing:inherit;。在Sass中也具備繼承一說,也是繼承類中的樣式代碼塊。在Sass中經過@extend來實現代碼塊的繼承,以下所示:

//SCSS
.btn {
  border: 1px solid #ccc;
  padding: 6px 10px;
  font-size: 14px;
}

.btn-primary {
  background-color: #f36;
  color: #fff;
  @extend .btn;
}

.btn-second {
  background-clor: orange;
  color: #fff;
  @extend .btn;
}
//CSS
.btn, .btn-primary, .btn-second {
  border: 1px solid #ccc;
  padding: 6px 10px;
  font-size: 14px;
}

.btn-primary {
  background-color: #f36;
  color: #fff;
}

.btn-second {
  background-clor: orange;
  color: #fff;
}

從示例代碼能夠看出,在Sass中的繼承也能夠繼承類中全部樣式代碼,並且編譯出來的CSS會將選擇器合併在一塊兒,造成組合選擇器:

.btn, .btn-primary, .btn-second { border: 1px solid #ccc; padding: 6px 10px; font-size: 14px; }
佔位符%placeholder

Sass中的佔位符%placeholder功能是一個很強大,很實用的一個功能,這也是我很是喜歡的功能。他能夠取代之前CSS中的基類形成的代碼冗餘的情形。由於%placeholder聲明的代碼,若是不被@extend調用的話,不會產生任何代碼。來看一個演示:

%mt5 { margin-top: 5px; }
%pt5{ padding-top: 5px; }

這段代碼沒有被@extend調用,他並無產生任何代碼塊,只是靜靜的躺在你的某個SCSS文件中。只有經過@extend調用纔會產生代碼:

//SCSS
%mt5 {
  margin-top: 5px;
}
%pt5{
  padding-top: 5px;
}

.btn {
  @extend %mt5;
  @extend %pt5;
}

.block {
  @extend %mt5;

  span {
    @extend %pt5;
  }
}
//CSS
.btn, .block {
  margin-top: 5px;
}

.btn, .block span {
  padding-top: 5px;
}

從編譯出來的CSS代碼能夠看出,經過@extend調用的佔位符,編譯出來的代碼會將相同的代碼合併在一塊兒。這也是咱們但願看到的效果,也讓你的代碼變得更爲乾淨。

擴展閱讀
混合宏 VS 繼承 VS 佔位符

初學者都經常糾結於這個問題「何時用混合宏,何時用繼承,何時使用佔位符?」其實他們更有更的優勢與缺點,先來看看他們使用效果:

//SCSS中混合宏使用
@mixin mt($var){
  margin-top: $var;  
}

.block { @include mt(5px);

  span {
    display:block;
    @include mt(5px);
  }
}

.header {
  color: orange;
  @include mt(5px);

  span{
    display:block;
    @include mt(5px);
  }
}
//CSS
.block { margin-top: 5px;
}
.block span { display: block;
  margin-top: 5px;
}

.header {
  color: orange;
  margin-top: 5px;
}
.header span {
  display: block;
  margin-top: 5px;
}

編譯出來的CSS清晰告訴了你們,他不會自動合併相同的樣式代碼,若是在樣式文件中調用同一個混合宏,會產生多個對應的樣式代碼,形成代碼的冗餘,這也是CSSer沒法忍受的一件事情。不過他並非一無事處,他能夠傳參數。我的建議:若是你的代碼塊中涉及到變量,建議使用混合宏來建立相同的代碼塊。

一樣的,將上面代碼中的混合宏,使用類名來表示,而後經過繼承來調用:

//SCSS 繼承的運用
.mt{
  margin-top: 5px;  
}

.block { @extend .mt;

  span {
    display:block;
    @extend .mt;
  }
}

.header {
  color: orange;
  @extend .mt;

  span{
    display:block;
    @extend .mt;
  }
}
//CSS
.mt, .block, .block span, .header, .header span { margin-top: 5px;
}

.block span { display: block;
}

.header {
  color: orange;
}
.header span {
  display: block;
}

使用繼承後,編譯出來的CSS會將使用繼承的代碼塊合併到一塊兒,經過組合選擇器的方式向你們展示,好比.mt, .block, .block span, .header, .header span。這樣編譯出來的代碼相對於混合宏來講要乾淨的多,也是CSSer指望看到。可是他不能傳變量參數。我的建議:若是你的代碼塊不須要專任何變量參數,並且有一個基類已在文件中存在,那麼建議使用Sass的繼承。

最後來看佔位符,將上面代碼中的基類.mt換成Sass的佔位符格式:

//SCSS中佔位符的使用
%mt{
  margin-top: 5px;  
}

.block { @extend %mt;

  span {
    display:block;
    @extend %mt;
  }
}

.header {
  color: orange;
  @extend %mt;

  span{
    display:block;
    @extend %mt;
  }
}
//CSS
.block, .block span, .header, .header span { margin-top: 5px;
}

.block span { display: block;
}

.header {
  color: orange;
}
.header span {
  display: block;
}

編譯出來的CSS代碼和使用繼承基本上是相同,只是不會在代碼中生成佔位符mt的選擇器。那麼佔位符和繼承的主要區別的,「佔位符是獨立定義,不調用的時候是不會在CSS中產生任何代碼;繼承是首先有一個基類存在,無論調用與不調用,基類的樣式都將會出如今編譯出來的CSS代碼中。」

經過對比,總結一下:

- 混合宏@mixin:若是相同代碼塊須要在不一樣的環境傳遞不一樣的值時,能夠經過混合宏來定義重複使用的代碼塊,其不足之處就是編譯出來的CSS代碼什麼屢次出現調用的混合宏對應的代碼塊,使用文件變得臃腫,代碼冗餘。 - 繼承:若是相同代碼塊不須要傳遞不一樣的值,而且此代碼塊已在Sass文件中定義,此進能夠經過Sass的繼承來調用已存在的基類。使用繼承將會將調用相同基類的代碼合併在一塊兒。不足之處時,若是基類,並不存在於HTML結構時,無論調用與不調用,在編譯出來的CSS中都將產生基類對應的樣式代碼。 - 佔位符%placeholder:佔位和繼承基本相似,惟一不一樣的是,相同代碼塊並無在基類中存中,而是額外聲明。若是不調用已聲明的佔位符,將不會產生任何樣式代碼,若是在不一樣選擇器調用佔位符,那麼編譯出來的CSS代碼將會把相同的代碼合併在一塊兒。

擴展閱讀
單類 VS 多類

在這種情形之下,引出一個新的爭論點,那就是單類與多類的火拼。在實際項目中應該使用哪一種方式。對於這樣的爭論一不是一時半刻的事情,其實他們一直都還在爭論,而倒底應該使用單類仍是多類,到目前也尚未結果。我的以爲仍是根據實際狀況出發吧。若是您對這方面的討論和相關知識點感興趣的話,不仿看看下面相關文章:

咱們回過來頭來細想,使用單類,在CSS中可能會形成代碼的冗餘,難於維護;而使用多類更易維護,並且代碼更乾淨。但單類在HTML中更具語法義,也無需過多去維護HTML;若是使用多類,在HTML中語義化規劃更具難度,對於結構也更難維護。其實將Sass結合在一塊兒,將不會這麼糾結。早前在寫CSS的時候不少同窗喜歡這樣寫:

//CSS
.paxs{padding:5px;}
.pas {padding: 10px;}
.pam{padding:15px;}
.pal{padding:20px;}
.paxl{padding: 25px;}
.paxxl{padding: 30px;}

.maxs{margin:5px;}
.mas {margin: 10px;}
.mam{margin:15px;}
.mal{margin:20px;}
.maxl{margin: 25px;}
.maxxl{margin: 30px;}

你的項目中可能會有一個基類文件,好比common.css,裏面放了不少相似於上面的代碼,而後在結構中經過多類引用:

//HTML
<div class="header maxs paxs"></div>

雖然這種方式解決了你的需求,但若是你的marginpadding值修改後,你須要同時修改你的HTML代碼,或者在CSS中經過覆蓋的方式來完成。但在Sass中,咱們能夠這樣使用:

//SCSS中定義%placeholder,能夠將這一部分代碼放在_help.scss中
%paxs{padding:5px;}
%pas {padding: 10px;}
%pam{padding:15px;}
%pal{padding:20px;}
%paxl{padding: 25px;}
%paxxl{padding: 30px;}

%maxs{margin:5px;}
%mas {margin: 10px;}
%mam{margin:15px;}
%mal{margin:20px;}
%maxl{margin: 25px;}
%maxxl{margin: 30px;}

//實際中引用
.header {
    @extend %paxs;
    @extend %maxs;
}

//CSS
.header {
    padding:5px;
    margin:5px;
}

在HTML中,只須要引用單類:

//HTML
<div class="header"></div>

這種情形之下,就算你要修改marginpadding值,你也只須要經過修改.scss文件,無需修改任何HTML文件中代碼便可。

相比之下,在實際中如何使用,或者你將選擇單類仍是多類方式,能夠權衡其利弊。

嵌套

Sass中還提供了選擇器嵌套功能,但這也並不意味着你在Sass中的嵌套是無節制的,由於你嵌套的層級越深,編譯出來的CSS代碼,選擇器層級將越深,這每每是你們不肯意看到的一點。好比:

//SCSS
.block { color: green;

  span {
    color: blue;

    a {
      color: orange;

      i{
        color: lime;

        em &{
          color: red;
        }
      }
    }
  }
}
//CSS
.block { color: green;
}
.block span { color: blue;
}
.block span a { color: orange;
}
.block span a i { color: lime;
}
em .block span a i { color: red;
}

如此一來,在編寫Sass代碼時,使用選擇器嵌套仍是須要遵循必定的原則,其中最關鍵之處:別讓你的嵌套層級超過四層。

//SCSS
.block { color: green;

  span {
    color: blue;
  }

  a {
    color: orange;
  }

  i{
    color: lime;

    em &{
      color: red;
    }
  }
}
//CSS
.block { color: green;
}
.block span { color: blue;
}
.block a { color: orange;
}
.block i { color: lime;
}
em .block i { color: red;
}
擴展閱讀
運算符

Sass還提供了一些運算符,能夠在代碼中作一些簡單的計算,其中包括+-*/等。

//SCSS
$hello: hello;
$world: world;
$width: 200px;

.string {
  sting: $hello + $world;
}
body {
  width: $width * 2;
}
//CSS
.string {
  sting: helloworld;
}

body {
  width: 400px;
}

使用Sass運算符作一些運算時,在運算符先後要留有空格。其中特別要注意的是font屬性中font-sizeline-height簡寫時,其中/分隔線與運算符中的除號/相同,無論你是這樣寫:

//SCSS
$font-size: 2em;
$line-height: 1.5;
$font-family: "Arial";
body {
  font: $font-size / $line-height $font-family;
}
//CSS
body {
  font: 1.3333333333em "Arial";
}

仍是這樣寫:

//SCSS
$font-size: 2em;
$line-height: 1.5;
$font-family: "Arial";
body {
  font: $font-size/$line-height $font-family;
}
//CSS
body {
  font: 1.33333em "Arial";
}

都將出錯。此時你須要使用Sass中的插值#{}:

//SCSS
$font-size: 2em;
$line-height: 1.5;
$font-family: "Arial";
body {
  font: $font-size/#{$line-height} $font-family;
}
//CSS
body {
  font: 2em/1.5 "Arial";
}

一樣的道理,在CSS屬性中碰到縮寫屬性帶有/符號的,在編寫Sass代碼時都需使用插值#{},以避免形成沒必要要的編譯錯誤。

選擇符&

連體符&在Sass中也是一個頗有意思,一個奇特的東東。特別是在選擇器的嵌套,BEM+Sass的運用中,其發揮着不同凡響的功能。看代碼中的演示,將會來得實際一些:

//SCSS
.block { color: green;

  &:after {
    content:"";
    display:table;
  }
  #{&}__element{
    color:orange;
  }
  #{&}--modify{
    color:blue;
  }
  &.info {
    color: lime;
  }
  .page &{
    color: yellow;
  }
}
//CSS
.block { color: green;
}
.block:after {
  content: "";
  display: table;
}
.block .block__element { color: orange;
}
.block .block--modify { color: blue;
}
.block.info { color: lime;
}
.page .block { color: yellow;
}

&的奧妙盡在代碼之中。其實你變換他的位置,簡單點說吧,配合選擇器嵌套,將會產生更多種不一樣組合效果,上面代碼演示的是最多見的效果。若是您感興趣,能夠本身探索探索。

擴展閱讀
列表$list

Sass中的List是一個讓人可愛又可恨的東西。主要是他的語法太寬鬆,你幾乎能夠作任何你想作的事情。若是要想更好的使用好Sass語言中的List功能,咱們就必須的深刻了解他。在這裏沒法詳細的闡述Sass中的List是怎麼一回事,咱們來看點簡單的。

在Sass中,聲明List和聲明變量很是的類似,並且其聲明的方式方法也是多樣,主要由於其語法很是寬鬆,如:

//定義變量
$list:();//定義一個空的列表
$list:(#b4d455,42,"awesome");
$list-space: "item-1" "item-2" "item-3";
//定義一個多維列表
$list: ( 
    ("item-1.1", "item-1.2", "item-1.3"), 
    ("item-2.1", "item-2.2", "item-2.3"),
    ("item-3.1", "item-3.2", "item-3.3")
);

在實際運用中,Sass的列表配合控制命令@each@for之類,或者函數nth()能夠作不少事情,來看一個簡單示例:

//SCSS
$list:(#b4d455,42,"awesome");
body {
  color: nth($list,1);  
  font-size: nth($list,2) * length($list) + px;
  font-family: nth($list,3);
}
//CSS
body {
  color: #b4d455;
  font-size: 126px;
  font-family: "awesome";
}
擴展閱讀
函數@function

在Sass中除了能夠定義變量,具備@extend,%placeholders和Mixins等特性以外,還自備了一系列的函數功能。其主要包括字符串函數、數字函數、列表函數、Introspection函數以及三元函數等。

字符串函數
數字函數
列表函數
Introspection函數
Miscellaneous函數

在這裏把Miscellaneous函數稱爲三元條件函數,主要由於他和JavaScript中的三元判斷很是的類似。他有兩個值,當條件成立返回一種值,當條件不成立時返回另外一種值:

if($condition,$if-true,$if-false)

上面表達式的意思是當$condition條件成立時,返回的值爲$if-true,不然返回的是$if-false值。

除了這些函數以外,Sass還有顏色函數,以及後面新增的Maps函數選擇器函數。有關於Sass全部自帶函數的使用,還能夠查看官網的函數列表

自定義函數

不少時候,Sass自帶的函數是沒法知足業務的需求,這個時候,用戶還能夠根據本身的需求定義函數。如:將px轉換成rem:

//SCSS
@function pxTorem($px,$browser-default-font-size){
    @return $px / $browser-default-font-size * 1rem;
}

h2 {
  font-size: pxTorem(32px,16px);
}
//CSS
h2 {
  font-size: 2rem;
}
擴展閱讀
map

Sass3.3新增了一個功能特性,那就是map。它能夠幫助更好的組織Sass代碼。從外形上看map長得有點相似於$list,其實你能夠將其理解成相似其餘語言中的數組,或JSON。在此就不作過多糾結,來簡單看看他長得樣子:

$map: (
  key: value,
  other-key: other-value
);

複雜一點的,能夠map裏面套map(記得前面的$list也能夠是多層$lsit)。

// _config.scss
$breakpoints: (
  small: 767px,
  medium: 992px,
  large: 1200px
);

// _mixins.scss
@mixin respond-to($breakpoint) { 
  @if map-has-key($breakpoints, $breakpoint) {
    @media (min-width: #{map-get($breakpoints, $breakpoint)}) {
      @content;
    }
  }

  @else {
    @warn "Unfortunately, no value could be retrieved from `#{$breakpoint}`. "
        + "Please make sure it is defined in `$breakpoints` map.";
  }
}

// _component.scss
.element {
  color: hotpink;

  @include respond-to(small) {
    color: tomato;
  }
}

上面這個就是使用了map管理斷點的一個示例,其編譯出來的代碼:

.element { color: hotpink; }

@media (min-width: 767px) {
  .element { color: tomato; }
}

Sass中的map能夠作的事情很是的多,特別藉助Sass提供的map函數功能,能幫你作更多更有意義的事情,除此以外,你還能夠開發一些適合本身業務需求的函數。

須要特別聲明的是,Sass中的map有前面介紹的"Sourcemap"可不是同一個東東,千萬別混淆了。

擴展閱讀
控制命令

Sass中控制命令指的是@if@each@for@while。具備必定的邏輯判斷和循環遍歷能力,這個對於懂JavaScript或者後端語言的同窗來講一點都不難。對在CSS中是難以想象的一件事情,最起碼到目前爲止是不太可能的事情。但在Sass這樣的CSS預處理器語言中實現了(固然,在LESS和Stylus中也具有這方面功能)。

@if

@if是一個條件判斷語句,簡單點的就是若是條件成立,處理什麼,反之條件不成立處理什麼?在Sass中除了@if以外,還能夠配合@else一塊兒使用:

//SCSS
@mixin blockOrHidden($boolean:true) {
  @if $boolean {
    @debug "$boolean is #{$boolean}";
      display: block;
    }
    @else {
      @debug "$boolean is #{$boolean}";
      display: none;
    }
}

.block {
  @include blockOrHidden;
}

.hidden{
  @include blockOrHidden(false);
}
//CSS
.block {
  display: block;
}

.hidden {
  display: none;
}
@each

@each是用來作遍歷的,在Sass中$list中的值要一個一個輸出,那麼就可使用@each命令來遍歷輸出。簡單點,他們裏面有必定的規律,讓其按必定的規律輸出。

//SCSS
$socials: twitter facebook twitter google rss email;

@mixin icon-socials {
  @each $social in $socials {
    .iocn-#{$social} {
      background: url("../images/#{$social}.png") no-repeat;
    }
  }
}

@include icon-socials;

//CSS
.iocn-twitter {
  background: url("../images/twitter.png") no-repeat;
}

.iocn-facebook {
  background: url("../images/facebook.png") no-repeat;
}

.iocn-twitter {
  background: url("../images/twitter.png") no-repeat;
}

.iocn-google {
  background: url("../images/google.png") no-repeat;
}

.iocn-rss {
  background: url("../images/rss.png") no-repeat;
}

.iocn-email {
  background: url("../images/email.png") no-repeat;
}

這個在Icon的運行中特別實用,上面演示的仍是簡單的一種,其實還能夠更復雜一些:

//SCSS
$socials: twitter facebook twitter google rss email;

@mixin icon-socials {
  @each $social in $socials {
    .iocn-#{$social} {
      background: url("../images/icon.png") no-repeat 0  (-(index($socials,$social)) * 60px);
    }
  }
}

@include icon-socials;
//CSS
.iocn-twitter {
  background: url("../images/icon.png") no-repeat 0 -60px;
}

.iocn-facebook {
  background: url("../images/icon.png") no-repeat 0 -120px;
}

.iocn-twitter {
  background: url("../images/icon.png") no-repeat 0 -60px;
}

.iocn-google {
  background: url("../images/icon.png") no-repeat 0 -240px;
}

.iocn-rss {
  background: url("../images/icon.png") no-repeat 0 -300px;
}

.iocn-email {
  background: url("../images/icon.png") no-repeat 0 -360px;
}
@for

Sass中的@for是一種循環遍歷。他有兩種方式:

@for $var from <start> through <end>

@for $var from <start> to <end>

其功能都是相似,只是截止的點不一同。來看一個對比示例:

//SCSS 
$grid-prefix: span !default;
$grid-width: 60px !default;
$grid-gutter: 20px !default;

%grid {
  float: left;
  margin-left: $grid-gutter / 2;
  margin-right: $grid-gutter / 2;
}
@for $i from 1 through 12 {
  .#{$grid-prefix}#{$i}{
    width: $grid-width * $i + $grid-gutter * ($i - 1);
    @extend %grid;
  }  
}

將上面的代碼稍作修改,將@for through方式換成@for to:

//SCSS
@for $i from 1 to 13 {
  .#{$grid-prefix}#{$i}{
    width: $grid-width * $i + $grid-gutter * ($i - 1);
    @extend %grid;
  }  
}

這兩種方式編譯出來的結果:

.span1, .span2, .span3, .span4, .span5, .span6, .span7, .span8, .span9, .span10, .span11, .span12 { float: left; margin-left: 10px; margin-right: 10px; }

.span1 { width: 60px; }

.span2 { width: 140px; }

.span3 { width: 220px; }

.span4 { width: 300px; }

.span5 { width: 380px; }

.span6 { width: 460px; }

.span7 { width: 540px; }

.span8 { width: 620px; }

.span9 { width: 700px; }

.span10 { width: 780px; }

.span11 { width: 860px; }

.span12 { width: 940px; }

這兩段Sass代碼並沒有太多差異,只是@for中的<end>取值不一樣。配合through<end>值是12,其遍歷出來的終點值也是12,和<end>值同樣。配合to<end>值是13,其遍歷出來的終點值是12,就是<end>對就的值減去1

@while

@while也能夠作到遍歷的效果,好比:

//SCSS
$types: 4;
$type-width: 20px;

@while $types > 0 {
    .while-#{$types} {
        width: $type-width + $types;
    }
    $types: $types - 1;
}
//CSS
.while-4 {
  width: 24px;
}

.while-3 {
  width: 23px;
}

.while-2 {
  width: 22px;
}

.while-1 {
  width: 21px;
}

在Sass中,@if@each@for@while這些控制命令配合@mixin@function能夠實現一些複雜的功能。有興趣的同窗能夠去嘗試一下。

擴展閱讀
@at-root

@at-root從字面說就是在根上。其實@at-root早期是爲BEM而生的,好比《Sass @at-root》一文中所介紹的。不過新的Sass對這個功能作出了調整。

在介紹選擇器嵌套時,爲了不編譯出來的CSS選擇器不會由於Sass中嵌套過深而層級過多,在編寫Sass代碼時,儘可能讓嵌套層級不要超過三層。但每每使用嵌套都是爲了更好的將代碼按功能塊來寫。Sass考慮到能讓開發員快速將編寫的代碼跳出層級限制,而又不使用編譯出來的代碼選擇器冗餘。將@at-root用於此處。來看一個示例:

//SCSS
.block { color: green;

  ul {
    list-style:none outside none;

    li {
      margin:0;

      @at-root a {
        color:green;
      }
    }
  }
}
//CSS
.block { color: green;
}
.block ul { list-style: none outside none;
}
.block ul li { margin: 0;
}
a {
  color: green;
}

編譯出來的a直接跳出去了。但這也不是你們想要的,若是不想徹底跳到最外面,那麼@at-root又歇菜了,不過稍加改良一下,就OK。看兩個@mixin:

//SCSS
@mixin parent-nth-status($index, $status, $place: suffix) {
  $func-name: parent-nth-status;
  $new-selectors: ();
  $selectors: &;

  $status: unquote($status);
  $place: unquote($place);

  @if not $selectors {
    @error "#{$func-name} should not at root!";
  }

  @if not $status or $status == "" {
    @error "#{$func-name} parameter $status error";
  }

  @each $selector in $selectors {
    $len: length($selector);
    $index: if($index < 0, $len + $index + 1, $index);
    $result: ();

    @for $i from 1 through $len {
      $item: nth($selector, $i);

      @if $i == $index {
        @if $place == suffix {
          $result: $item + $status;
        } @else if $place == prefix {
          $result: $status + $item;
        } @else if $place == prepend {
          $result: append($status, $item);
        } @else if $place == append {
          $result: append($item, $status);
        }
      }
      @else {
        $result: append($result, $item);
      }

    }

    $new-selectors: append($new-selectors, $result, comma);
  }

  @at-root #{$new-selectors} {
    @content;
  }
}
@mixin parent-status($status, $place: suffix) {
  @include parent-nth-status(-2, $status, $place) {
    @content;
  }
}
.tab {
  a {
    display: inline-block;
    padding: 10px 60px;
    cursor: pointer;
    &:hover {
      background: #AAA;
    }
    i {
      margin-left: 10px;
      @include parent-status(':hover') { color: red; }
      @include parent-status('.home-link') { background: blue; }
      @include parent-status('.about-link') { background: green; }
    }
  }
}

//CSS
.tab a {
  display: inline-block;
  padding: 10px 60px;
  cursor: pointer;
}
.tab a:hover {
  background: #AAA;
}
.tab a i {
  margin-left: 10px;
}
a:hover i {
  color: red;
}
a.home-link i {
  background: blue;
}
a.about-link i {
  background: green;
}

是否是讓你以爲一下爽了。

如何在項目中使用Sass?

不少時候,你們更爲關心的如何在項目中使用Sass。其實這是一個很簡單的問題,只是從未動手過而以。這裏說說是怎麼將Sass和項目結合在一塊兒。

在平時作項目的時候,項目中都會包括幾個經常使用的文件目錄:

  • css:主要放置.css文件
  • js:主要放置.js文件
  • images:主要放置圖片文件
  • html:主要放置.html.php之類文件(我通常喜歡直接放在項目根錄下)

而Sass用到項目中並和上面無太多的差異,只須要在項目中建立一個sass目錄,好放置.scss或者.sass文件。前面也說過了,最終在Web調用的文件是編譯出來的.css文件。在沒有必定經驗的時候,能夠將全部的.scss文件放在sass目錄中。你也能夠將其細分出來,由於不少代碼不僅用於一個項目,能夠用到其餘項目當中,我經常是這樣組織個人.scss文件:

項目組織結構:

Sass項目組織結構

sass目錄結構:

Sass項目組織結構

style.scss文件引用:

Sass項目組織結構

這是一個簡單的項目,其實喜歡Sass的同窗,能夠看看其餘項目的是如何組織相關文件,好比說Foundation、Bootstrap和Compass等。

擴展閱讀

OOSass

OOSass其實就是將OOCSS和Sass二者結合在一塊兒的產物。雖然OOCSS給咱們寫樣式帶來重大的變革,但依舊是痛楚不斷。其實將OOCSS和Sass結合在一塊兒,你將再也不那麼痛苦。在此,用一個簡單的示例來演示整個過程。

下面有兩很拙的按鈕:

Sass項目組織結構

不能再拙的按鈕了,咱也不糾結了。記得當初剛接觸這個行業時,我傻傻這樣作:

HTML
<a href="#" class="twitter">Twitter</a>
<a href="#" class="facebook">Facebook</a>
CSS
.twitter { border:3px solid #000; padding:10px 20px; color:#fff; border-radius:10px; background:red; text-decoration: none; }
.facebook { border:3px solid #000; padding:10px 20px; color:#fff; border-radius:10px; background:blue; text-decoration: none; }

忽然發現,兩個按鈕長得差很少,只是背景色不一樣而以,後來知道相同的樣式能夠合併在一塊兒,因而我知道這樣作也能夠,還比前面方便一點:

.twitter,.facebook{ border:3px solid #000; padding:10px 20px; color:#fff; border-radius:10px; text-decoration: none; }
.twitter { background:red; }
.facebook { background:blue; }

惟一變化,就是將.twitter.facebook兩個選擇器合併到一塊兒,使用公用樣式部分。但也麻煩,若是有一天,我新增了.google.rss等按鈕呢?使用公用樣式部分的選擇器會變得很是的長,並且要不斷的手工去添加。

隨着看得多了,稍有點經驗以後,我懂得給他們加一個公用的類名:

<a href="#" class=「btn btn-twitter」>Twitter</a>
<a href="#" class=「btn btn-facebook」>Facebook</a>

將公用的樣式都寫在.btn類名上面:

.btn{ border:3px solid #000; padding:10px 20px; color:#fff; border-radius:10px; text-decoration: none; }
.btn-twitter { background:red; }
.btn-facebook { background:blue; }

納尼?這樣也行。話說比前面方便些了,可又扯出另外一個蛋疼的東西了,都得去動HTML。那麼問題來了,有什麼辦法既不用動結構,又不用寫那麼多樣式代碼 ?其實這就是接下來要說的。這種情形Sass會變得更完美一些。

回到最初狀態,我仍是將結構寫成:

<a href="#" class=「btn-twitter」>Twitter</a>
<a href="#" class=「btn-facebook」>Facebook</a>

在Sass中我先考慮到使用一個@mixin,將公用樣式都賦予給這個@mixin

@mixin btn{
  border:3px solid #000;
  padding:10px 20px;
  color:#fff;
  border-radius:10px;
  text-decoration: none;
}

而後在實際中調用:

.btn-twitter {
  background:red;
  @include btn;
}
.btn-facebook {
  background:blue;
  @include btn;
}

編譯出來的CSS:

.btn-twitter { background: red; border: 3px solid #000; padding: 10px 20px; color: #fff; border-radius: 10px; text-decoration: none; }
.btn-facebook { background: blue; border: 3px solid #000; padding: 10px 20px; color: #fff; border-radius: 10px; text-decoration: none; }

編譯出來的代碼跟初學CSS寫出來的代碼無兩樣。這對於一個有經驗的CSSer來講,彷佛沒法接受。那就接着改良,我們不使用@mixin了,而換成基類.btn,而後經過@extend來繼承:

.btn{
  border:3px solid #000;
  padding:10px 20px;
  color:#fff;
  border-radius:10px;
  text-decoration: none;
}
.btn-twitter {
  background:red;
  @extend .btn;
}
.btn-facebook {
  background:blue;
  @extend .btn;
}

編譯出來的代碼:

.btn, .btn-twitter, .btn-facebook { border: 3px solid #000; padding: 10px 20px; color: #fff; border-radius: 10px; text-decoration: none; }
.btn-twitter { background: red; }
.btn-facebook { background: blue; }

這個回到當初選擇器合併狀態了,糾結的是,我原本只須要用的選擇器合併在一塊兒,如今還多了一個基類的,真是多此一舉。得繼續改,這回咱使用佔位符%

%btn{
  border:3px solid #000;
  padding:10px 20px;
  color:#fff;
  border-radius:10px;
  text-decoration: none;
}
.btn-twitter {
  background:red;
  @extend %btn;
}
.btn-facebook {
  background:blue;
  @extend %btn;
}

編譯出來的CSS:

.btn-twitter, .btn-facebook { border: 3px solid #000; padding: 10px 20px; color: #fff; border-radius: 10px; text-decoration: none; }
.btn-twitter { background: red; }
.btn-facebook { background: blue; }

這樣舒服多了,就算你還要增長新的按鈕,這種方式也就只須要調用了。而不須要再去考慮HTML。

其實除了上面的方法以外,還可使用Sass的map功能:

//SCSS
$vars:(
  prefix-class: btn,
  twitter: red,
  facebook: blue
);
%btn{
  border:3px solid #000;
  padding:10px 20px;
  color:#fff;
  border-radius:10px;
  text-decoration: none;
}
.#{map-get($vars,prefix-class)}-twitter {
  background:map-get($vars,twitter);
  @extend %btn;
}
.#{map-get($vars,prefix-class)}-facebook {
  background:map-get($vars,facebook);
  @extend %btn;
}
//CSS
.btn-twitter, .btn-facebook {
  border: 3px solid #000;
  padding: 10px 20px;
  color: #fff;
  border-radius: 10px;
  text-decoration: none;
}
.btn-twitter {
  background: red;
}
.btn-facebook {
  background: blue;
}

其實實現上面的效果,在Sass中方法還有不少,你們應該經過實戰或者經驗,找出最適合本身的一種方案。

擴展閱讀

編寫Sass的技巧

編寫Sass和CSS是相似的,初學者可能編寫出來的Sass代碼並不完美,甚至還會形成編譯出來的CSS代碼比本身使用CSS寫出來的代碼更垃圾。也不少同窗由於這個緣由而放棄了使用Sass這個高效的預處理器語言。其實不用擔憂,當你看得多、寫得多、總結得多的時候,你的Sass代碼會愈來愈優秀。總結幾點我寫Sass代碼的體驗:

  • 組織好Sass文件:這一步很是重要,由於其直接影響你如何@import文件,更直接會影響你編譯出來的代碼會不會重複;
  • 有效使用Sass變量:Sass變量雖強大,但並非一味的將全部東西都定義爲變量,一難維護,二也不必定所有使用上;
  • 減小對混合宏@mixin的依賴:@include進來@mixin,將會讓你的代碼變得更爲冗餘,保持一點,若是共用樣式不涉及變量參數,堅定不使用混合宏來定義;
  • 擁抱%placholder:佔位符%placeholder在Sass中是一個好東東,只要不須要變量的公用樣式(基類樣式)均可以將他們定義成%placholder;
  • 合理嵌套:保持你的嵌套不要超過三個層級,若是爲了更好的編寫或管理模塊而使用選擇器嵌套,也應該配合@at-root等相關功能,作到進退有度;
  • 使用@function作更多的事情:@function能夠幫助你定義更多的功能,幫你作更多的事情

其實使用Sass,你們應該時刻記得:*保持Sass的簡單***。

擴展閱讀

學習Sass的案例與資料

學習Sass其實最好的去處是Github。固然除了這個地方,你還能夠在本站閱讀Sass相關教程以及Sass中國網。下面列了幾個國外關注度較高的Sass開源項目:

其實@結一同窗也整理了幾個好東東:

若是你對Sass的@mixin@functions感興趣,能夠觀注我建立的一個庫,裏面整理了一些本身經常使用的@mixin@functions,並且仍是一個很是有用的資源收藏夾,收錄不少有關於Sass相關的教程與視頻。

Sass Mixins & Functions

總結

花了一週多的時間整理了這篇文章,也算是本身學習Sass以後的總結吧,也能夠說是系統的對W3cplus站上發佈的Sass教程的整理。但願這篇文章對你們學習Sass、瞭解Sass和使用Sass有所幫助。更但願的是,若是您有相關方面的經驗,但願與咱們一塊兒分享。

大漠

經常使用暱稱「大漠」,W3CPlus, Sass中國創始人,目前就任於Ctrip UED。中國Drupal社區核心成員之一。對HTML五、CSS3和Sass等前端腳本語言有很是深刻的認識和豐富的實踐經驗,尤爲專一對CSS3的研究,是國內最先研究和使用CSS3技術的一批人。CSS三、Sass和Drupal中國佈道者。2014年出版《 圖解CSS3:核心技術與案例實戰》。

如需轉載,煩請註明出處:http://www.w3cplus.com/preprocessor/sass-bring-change.html



相關文章
相關標籤/搜索