Sass又名SCSS,是CSS預處理器之一,,它能用來清晰地、結構化地描述文件樣式,有着比普通 CSS 更增強大的功能。 Sass 可以提供更簡潔、更優雅的語法,同時提供多種功能來建立可維護和管理的樣式表。如下是個人學習筆記。css
1.安裝sass(mac)html
①:Ruby安裝web
②:安裝sasschrome
sudo gem install sass
能夠經過 sass -v檢測是否完成安裝 json
2.更新sassgulp
gem update sass
3.卸載(刪除)sass瀏覽器
gem uninstall sass
Sass編譯調試sass
咱們如今通常採用scss語法格式。SCSS 是 Sass 的新語法格式,從外形上來判斷他和 CSS 長得幾乎是如出一轍,代碼都包裹在一對大括號裏,而且末尾結束處都有一個分號。其文件名格式以「.scss」爲擴展名。注意文件擴展名不能用.sass。koa
使用 Sass 進行開發,項目中仍是引用「.css」文件.Sass 只不過是作爲一個預處理工具,提早幫你作事情,只有你須要時候,它纔有攻效。 Sass 開發以後,要讓 Web 頁面能調用 Sass 寫好的東西,就得有一個編譯過程。ide
1.命令編譯:命令編譯是指使用你電腦中的命令終端,經過輸入 Sass 指令來編譯 Sass。這種編譯方式是最直接也是最簡單的一種方式。
①單文件編譯:(開啓「watch」功能,這樣只要你的代碼進行任保修改,都能自動監測到代碼的變化,而且給你直接編譯出來:)
sass --watch <要編譯的Sass文件路徑>/style.scss:<要輸出CSS文件路徑>/style.css (style是文件的名字)
②多文件編譯:(對整個項目全部 Sass 文件編譯成 CSS 文件,而且將這些 CSS 文件都放在項目中「css」文件夾中)
sass --watch sass/:css/
2.GUI界面工具編譯
3.自動化編譯
如下分別經過Grunt和Gulp來配置Sass的編譯
①:Grunt 配置 Sass 編譯的示例代碼
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 配置 Sass 編譯的示例代碼
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的編譯的過程當中,是否是支持「GBK」編碼的。因此在建立 Sass 文件時,就須要將文件編碼設置爲「utf-8」,在項目中文件命名或者文件目錄命名不要使用中文字符。
一、嵌套輸出方式 nested,在編譯的時候帶上參數「 --style nested」:
sass --watch test.scss:test.css --style nested
二、展開輸出方式 expanded,在編譯的時候帶上參數「 --style expanded」:
sass --watch test.scss:test.css --style expanded
三、緊湊輸出方式 compact,在編譯的時候帶上參數「 --style compact」:
sass --watch test.scss:test.css --style compact
4.壓縮輸出方式 compressed,在編譯的時候帶上參數「 --style compressed」:
sass --watch test.scss:test.css --style compressed
一段時間以後,你實際上就再也不須要寫 CSS 代碼了,只用寫 Sass 代碼。在這種狀況下,你只須要設定輸出格式爲壓縮格式,知道輸出的 CSS 代碼能夠直接使用便可。
這張圖表示的是,在chrome瀏覽器上改動相應的scss的樣式,效果會實時同步出來,而且改動的代碼會保存到本地。實現的方法能夠看這個教程。
如今實現並非一件難事,只要你的瀏覽器支持「sourcemap」功能便可。早一點的版本,須要在編譯的時候添加「--sourcemap」 參數:
sass --watch --scss --sourcemap style.scss:style.css
在 Sass3.3 版本之上,不須要添加這個參數也能夠:
sass --watch style.scss:style.css
聲明變量
定義以後能夠在全局範圍內使用。 $fontSize: 12px; body{ font-size:$fontSize; } 編譯後的css代碼: body{ font-size:12px; }
$baseLineHeight:1.5 !default; body{ line-height: $baseLineHeight; } 編譯後的css代碼: body{ line-height:1.5; }
//SCSS $color: orange !default;//定義全局變量(在選擇器、函數、混合宏...的外面定義的變量爲全局變量) .block { color: $color;//調用全局變量 } em { $color: red;//定義局部變量 a { color: $color;//調用局部變量 } } span { color: $color;//調用全局變量 }
應該少用。
一、選擇器嵌套
假設咱們有一段這樣的結構: <header> <nav> <a href=「##」>Home</a> <a href=「##」>About</a> <a href=「##」>Blog</a> </nav> <header> 想選中 header 中的 a 標籤,在寫 CSS 會這樣寫: nav a { color:red; } header nav a { color:green; } 那麼在 Sass 中,就可使用選擇器的嵌套來實現: nav { a { color: red; header & { color:green; } } }
二、屬性嵌套
Sass 中還提供屬性嵌套,CSS 有一些屬性前綴相同,只是後綴不同,好比:border-top/border-right,與這個相似的還有 margin、padding、font 等屬性。假設你的樣式中用到了: .box { border-top: 1px solid red; border-bottom: 1px solid green; } 在 Sass 中咱們能夠這樣寫: .box { border: { top: 1px solid red; bottom: 1px solid green; } }
三、僞類嵌套:僞類嵌套和屬性嵌套很是相似,只不過它須要藉助`&`符號一塊兒配合使用
咱們就拿經典的「clearfix」爲例吧: .clearfix{ &:before, &:after { content:""; display: table; } &:after { clear:both; overflow: hidden; } } 編譯出來的 CSS: clearfix:before, .clearfix:after { content: ""; display: table; } .clearfix:after { clear: both; overflow: hidden; }
混合宏
在 Sass 中,使用「@mixin」來聲明一個混合宏
不帶參數混合宏: @mixin border-radius{ -webkit-border-radius: 5px; border-radius: 5px; } 大括號裏面是複用的樣式代碼。 帶參數混合宏: @mixin border-radius($radius:5px){ -webkit-border-radius: $radius; border-radius: $radius; }
使用「@include」來調用一個混合宏
@mixin border-radius{ -webkit-border-radius: 3px; border-radius: 3px; } --------調用--------- button { @include border-radius; } 這個時候編譯出來的 CSS: button { -webkit-border-radius: 3px; border-radius: 3px; }
混合宏的參數--傳一個不帶值的參數
在混合宏中,能夠傳一個不帶任何值的參數,好比: @mixin border-radius($radius){ -webkit-border-radius: $radius; border-radius: $radius; } 在混合宏「border-radius」中定義了一個不帶任何值的參數「$radius」。 在調用的時候能夠給這個混合宏傳一個參數值: .box { @include border-radius(3px); } 編譯出來的 CSS: .box { -webkit-border-radius: 3px; border-radius: 3px; }
混合宏的參數--傳一個帶值的參數
在 Sass 的混合宏中,還能夠給混合宏的參數傳一個默認值,例如: @mixin border-radius($radius:3px){ -webkit-border-radius: $radius; border-radius: $radius; } 在調用相似這樣的混合宏時,會多有一個機會,假設你的頁面中的圓角不少地方都是「3px」的圓角,那麼這個時候只須要調用默認的混合宏「border-radius」: .btn { @include border-radius; } 編譯出來的 CSS: .btn { -webkit-border-radius: 3px; border-radius: 3px; }
混合宏的參數--傳多個參數
Sass 混合宏除了能傳一個參數以外,還能夠傳多個參數,如: @mixin center($width,$height){ width: $width; height: $height; position: absolute; top: 50%; left: 50%; margin-top: -($height) / 2; margin-left: -($width) / 2; } .box-center { @include center(500px,300px); } 編譯出來 CSS: .box-center { width: 500px; height: 300px; position: absolute; top: 50%; left: 50%; margin-top: -150px; margin-left: -250px; }
擴展/繼承
在 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-color: 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; }
佔位符 %:經過 @extend 調用的佔位符纔會產生效果,編譯出來的代碼會將相同的代碼合併在一塊兒。
%placeholder 聲明的代碼,若是不被 @extend 調用的話,不會產生任何代碼。 //SCSS %mt5 { margin-top: 5px; } %pt5{ padding-top: 5px; } .btn { @extend %mt5; @extend %pt5; } .block { @extend %mt5; span { @extend %pt5; } } 編譯出來的CSS //CSS .btn, .block { margin-top: 5px; } .btn, .block span { padding-top: 5px; } 從編譯出來的 CSS 代碼能夠看出,經過 @extend 調用的佔位符,編譯出來的代碼會將相同的代碼合併在一塊兒。這也是咱們但願看到的效果,也讓你的代碼變得更爲乾淨。
他們各有各的優勢與缺點,先來看看他們使用效果:
a) Sass 中的混合宏使用 @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); } } ---編譯出來的結果--- .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 沒法忍受的一件事情。不過他並非一無事處,他能夠傳參數。 我的建議:若是你的代碼塊中涉及到變量,建議使用混合宏來建立相同的代碼塊。
.mt{ margin-top: 5px; } .block { @extend .mt; span { display:block; @extend .mt; } } .header { color: orange; @extend .mt; span{ display:block; @extend .mt; } } ----編輯之後---- .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{ margin-top: 5px; } .block { @extend %mt; span { display:block; @extend %mt; } } .header { color: orange; @extend %mt; span{ display:block; @extend %mt; } } -----編譯之後------- .block, .block span, .header, .header span { margin-top: 5px; } .block span { display: block; } .header { color: orange; } .header span { display: block; } 總結:編譯出來的 CSS 代碼和使用繼承基本上是相同,只是不會在代碼中生成佔位符 mt 的選擇器。那麼佔位符和繼承的主要區別的,「佔位符是獨立定義,不調用的時候是不會在 CSS 中產生任何代碼;繼承是首先有一個基類存在,無論調用與不調用,基類的樣式都將會出如今編譯出來的 CSS 代碼中。」
註釋
一、相似 CSS 的註釋方式,使用 」/* 」開頭,結屬使用 」*/ 」 二、相似 JavaScript 的註釋方式,使用「//」 二者區別,前者會在編譯出來的 CSS 顯示,後者在編譯出來的 CSS 中不會顯示,來看一個示例: //定義一個佔位符 %mt5 { margin-top: 5px; } /*調用一個佔位符*/ .box { @extend %mt5; } 編譯出來的CSS .box { margin-top: 5px; } /*調用一個佔位符*/
加法運算是 Sass 中運算中的一種,在變量或屬性中均可以作加法運算。如: .box { width: 20px + 8in; } 編譯出來的 CSS: .box { width: 788px; } 但對於攜帶不一樣類型的單位時,在 Sass 中計算會報錯,以下例所示: .box { width: 20px + 1em; } 編譯的時候,編譯器會報錯:「Incompatible units: 'em' and ‘px'.」 總結:in mm cm pt pc px等絕對單位都能運算; ex em rem等相對當前字體的都不能運算 能換算的都會換算成px像素長度 不能換算的都會報編譯錯誤 有個例外就是不加單位的話就至關於0
Sass 的減法運算和加法運算相似,咱們經過一個簡單的示例來作闡述: $full-width: 960px; $sidebar-width: 200px; .content { width: $full-width - $sidebar-width; } 編譯出來的 CSS 以下: .content { width: 760px; }
Sass 中的乘法運算和前面介紹的加法與減法運算還略有不一樣。雖然他也可以支持多種單位(好比 em ,px , %),但當一個單位同時聲明兩個值時會有問題。好比下面的示例: .box { width:10px * 2px; } 編譯的時候報「20px*px isn't a valid CSS value.」錯誤信息。 若是進行乘法運算時,兩個值單位相同時,只須要爲一個數值提供單位便可。上面的示例能夠修改爲: .box { width: 10px * 2; } 編譯出來的 CSS: .box { width: 20px; }
」/ 」符號被看成除法運算符時有如下幾種狀況: • 若是數值或它的任意部分是存儲在一個變量中或是函數的返回值。 • 若是數值被圓括號包圍。 • 若是數值是另外一個數學表達式的一部分。 以下所示: //SCSS p { font: 10px/8px; // 純 CSS,不是除法運算 $width: 1000px; width: $width/2; // 使用了變量,是除法運算 width: round(1.5)/2; // 使用了函數,是除法運算 height: (500px/2); // 使用了圓括號,是除法運算 margin-left: 5px + 8px/2px; // 使用了加(+)號,是除法運算 } 編譯出來的CSS p { font: 10px/8px; width: 500px; height: 250px; margin-left: 9px; } 在除法運算時,若是兩個值帶有相同的單位值時,除法運算以後會獲得一個不帶單位的數值。以下所示: .box { width: (1000px / 100px); } 編譯出來的CSS以下: .box { width: 10; }