SASS入门与实践
前言
SASS是最古老,也是最成熟的CSS預(yù)處理語言,誕生于2007年。有著比LESS更強(qiáng)大的功能。不過最開始的縮進(jìn)式語法,并不能被廣大用戶接受,所以雖然出現(xiàn)很早但是普及卻不如LESS,但是隨著自身語法的改進(jìn)和Ruby on Rails的大力推進(jìn),絕大多數(shù)人都開始選用SASS作為自己的預(yù)處理器開發(fā)利器。官網(wǎng)給出的介紹是:它是一門高于CSS的元語言,能用來編寫清晰且結(jié)構(gòu)化的描述文件樣式,有著比普通CSS更強(qiáng)大的功能。提供更簡潔、更優(yōu)雅的語法,同時(shí)提供多種功能來創(chuàng)建可維護(hù)和管理的樣式表。
什么是CSS預(yù)處理器
CSS 預(yù)處理器用一種專門的編程語言,為 CSS 增加了一些編程的特性,進(jìn)行 Web 頁面樣式設(shè)計(jì),然后再編譯成正常的 CSS 文件,以供項(xiàng)目使用,特點(diǎn)是預(yù)處理器是一門單獨(dú)的語言,有變量、邏輯判斷、函數(shù),還有,使用時(shí),需要編譯成正常的CSS
CSS預(yù)處理器技術(shù)已經(jīng)非常成熟,當(dāng)然有許多不同的CSS預(yù)處理器,比如SASS/LESS/Stylus 等等,關(guān)于那種預(yù)處理器是最優(yōu)秀的,各大技術(shù)論壇爭論紛紛。本文將要介紹的就是能夠讓絕大多數(shù)前端開發(fā)工程師滿意的一種:SASS
SASS 和 SCSS
兩者其實(shí)是同一種東西,我們平時(shí)都稱之為Sass,兩者不同之處有以下兩點(diǎn)
-
文件擴(kuò)展名不同分別為.sass和.scss
-
語法書寫方式不同。SASS以嚴(yán)格縮進(jìn)式語法來編寫,不包含大括號和分號,類似Jade;而SCSS的語法書寫則和CSS的語法書寫非常類似,舉個(gè)栗子
SASS語法$font-stack: Helvetica, sans-serif //定義變量$primary-color: #333 //定義變量bodyfont: 100% $font-stackcolor: $primary-colorSCSS語法$font-stack: Helvetica, sans-serif;$primary-color: #333;body {font: 100% $font-stack;color: $primary-color;}兩者編譯出來的CSS文件body {font: 100% Helvetica, sans-serif;color: #333;} 復(fù)制代碼
可見,Sass和CSS的書寫語法差別很大,而Sass書寫則和CSS幾乎一樣,所以這也是為什么越來越多的前端開發(fā)使用Sass中的SCSS方式來開發(fā)的原因
Sass的安裝
MAC系統(tǒng)
- brew install ruby
- sudo gem install sass
- sass -v
Window系統(tǒng)
- 去官網(wǎng)下載Ruby安裝包
打開ruby 命令行
命令行輸入 gem install sass 復(fù)制代碼如果上面安裝失敗,可能是因?yàn)樵摪惭b途徑已經(jīng)被墻了,需要更換安裝的源,這里我們使用淘寶的源,附上安裝步驟
Sass基礎(chǔ)
接下來所說的所有語法書寫格式都是以.scss格式
基本格式
以.scss作為文件后綴,代碼在一組大括號內(nèi)且結(jié)束處都有一個(gè)分號作為結(jié)尾,同樣的CSS代碼
body {font: 100% Helvetica, sans-serif;color: #333; } 復(fù)制代碼我們使用SCSS語法格式將上面重寫一下
$font-stack: Helvetica, sans-serif; $primary-color: #333;body {font: 100% $font-stack;color: $primary-color; } 復(fù)制代碼編譯.scss文件
Sass是一個(gè)預(yù)處理器,將編寫的.scss文件編譯成對應(yīng)的.css文件,項(xiàng)目中使用的還是.css為后綴的文件。具體的編譯方式有三種:命令編譯、GUI編譯、自動化編譯
-
命令編譯:使用指令代碼進(jìn)行編譯
sass src/:out/
如 sass sass/:css/ 這條指令意味著把’sass’文件夾中的所有’.scss’文件編譯成’.css’文件,并把這些’.css’文件放置到css目錄下。這樣做的缺點(diǎn)是只能一次性編譯,每次更改后都需要重復(fù)編譯。
如果這樣做太麻煩的話,可以使用’watch’功能,watch功能會監(jiān)視指定文件的改動,自動執(zhí)行編譯
sass --watch src/:out/ 復(fù)制代碼-
GUI編譯:
推薦使用Koloa
-
自動化編譯:這里推薦使用 gulp
var gulp = require('gulp');var sass = require('gulp-ruby-sass');gulp.task('sass', function () {gulp.sass('./scss/*.scss').pipe(gulp.dest('./css'));});gulp.task('watch', function() {gulp.watch('scss/*.scss', ['sass']);});gulp.task('default', ['sass','watch']); 復(fù)制代碼 -
常見編譯問題
- Sass不支持‘GBK’編碼,所以在創(chuàng)建文件時(shí)就需要將編碼格式設(shè)置為’utf-8’
- 不建議在項(xiàng)目中的文件路徑或者文件名中出現(xiàn)中文漢字
不同的輸出風(fēng)格
Sass中編譯出來的樣式風(fēng)格可以按照不同的風(fēng)格進(jìn)行顯示。主要包括如下幾種
- 嵌套式輸出 nested
- 展開式輸出 expanded
- 緊湊式輸出 compact
- 壓縮式輸出 compressed
具體的輸出方式通過編譯指令完成
sass --watch test.scss:test.css --style nested 復(fù)制代碼對于如下的css樣式,分別舉例四種輸出方式
nav {ul {margin: 0;}li { display: inline-block; }a {display: block;} } 復(fù)制代碼-
嵌套式輸出 nested
nav ul {margin: 0; }nav li {display: inline-block; }nav a {display: block;} 復(fù)制代碼 -
展開式輸出 expanded(和nested類似,但是大括號獨(dú)占一行)
nav ul {margin: 0; }nav li {display: inline-block; }nav a {display: block;} 復(fù)制代碼 -
緊湊型輸出 compact
nav ul { margin: 0; }nav li { display: inline-block; }nav a { display: block;} 復(fù)制代碼 -
壓縮性輸出 compressed
nav ul{margin:0;padding:0;}nav li{display:inline-block}nav a{display:block;} 復(fù)制代碼
SCSS 語法
變量
- 聲明變量
Sass中變量包含三部分:$、變量名稱、變量值,如
$width: 300px 復(fù)制代碼-
變量類型
-
普通變量
$fontSize: 12px;body{font-size: $fontSize; } 復(fù)制代碼 -
默認(rèn)變量:僅需要在值得后面加上 !default
$baseLineHeight:1.5 !default;body{line-height: $baseLineHeight; } 復(fù)制代碼
-
類似于JavaScript中的短路賦值 var onePoint = req.query.from || ‘China’;
變量的調(diào)用
直接在需要賦值的地方使用$ 變量名就可以完成調(diào)用
作用域
分為全局作用域和局部作用域
$color: orange !default;//定義全局變量.block {color: $color;//調(diào)用全局變量,orange }em {$color: red;//定義局部變量a {color: $color;//調(diào)用局部變量,red} } 復(fù)制代碼混合宏
使用混合宏可以自定義重復(fù)利用的而組件,關(guān)鍵字是 @mixin。在混合宏中,我們可以自定義代碼的樣式,添加判斷邏輯等等
-
混合宏的聲明
不帶參數(shù)的混合宏
@mixin border-radius {-webkit-border-radius: 5px;border-radius: 5px;} 復(fù)制代碼帶參數(shù)的混合宏:入?yún)⑷绻淮嬖谑褂媚J(rèn)的5px。這個(gè)5px可以是頁面的默認(rèn)屬性,而特殊的border-radius則可以在調(diào)用是通過入?yún)⒖刂?/p> @mixin border-radius($radius:5px){-webkit-border-radius: $radius;border-radius: $radius;} 復(fù)制代碼
-
調(diào)用混合宏
調(diào)用不帶參數(shù)的混合宏(上文中定義的)
button {@include border-radius;} 復(fù)制代碼調(diào)用帶參數(shù)的混合宏
button {@include border-radius(3px);} 復(fù)制代碼
混合宏的不足
混合宏可以解決重復(fù)代碼塊的問題,但是也有不足。最大的不足之處在于混合宏會生成冗余的代碼塊,比如在不同的地方調(diào)用一個(gè)相同的混合宏時(shí)。
@mixin border-radius{-webkit-border-radius: 3px;border-radius: 3px; }.box {@include border-radius;margin-bottom: 5px; }.btn {@include border-radius; } 復(fù)制代碼生成的CSS內(nèi)容如下
.box {-webkit-border-radius: 3px;border-radius: 3px;margin-bottom: 5px; }.btn {-webkit-border-radius: 3px;border-radius: 3px; } 復(fù)制代碼可以看出兩個(gè)地方調(diào)用混合宏,兩個(gè)地方都出現(xiàn)了混合宏的代碼內(nèi)容,并沒有只能的將相同的代碼進(jìn)行合并成如下的樣式。
.box .btn{-webkit-border-radius: 3px;border-radius: 3px; }.box {margin-bottom: 5px; } 復(fù)制代碼@extend 繼承
CSS原本就有繼承機(jī)制的,內(nèi)部元素默認(rèn)會繼承外部元素的某些屬性。Sass中也有繼承這么一說,通過@extend來繼承已經(jīng)存在的代碼塊。
.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; } 復(fù)制代碼編譯后
.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; } 復(fù)制代碼從示例代碼中我們可以看出,在Sass中的繼承,可以繼承類樣式中的所有代碼,而編譯出的CSS會合并到一起,形成組合選擇器.btn, .btn-primary, .btn-second {}的形式
混合宏定義了一個(gè)可以支持參數(shù)傳遞的復(fù)用代碼塊,但是代碼塊本身必不能直接作為樣式;繼承作為雖然不能提供參數(shù)傳遞的復(fù)用代碼塊,但是父類本身可以作為樣式~
占位符
Sass中的占位符 %placeholder 類似于繼承中的基類,可以通過@extend繼承選中基類中的代碼。但是不同的是通過占位符聲明的代碼,如果不被@extend的話,不會產(chǎn)生任何代碼,所以和繼承是有差別的,舉個(gè)栗子。
%mt5 {margin-top: 5px; } %pt5{padding-top: 5px; }.btn {@extend %mt5;@extend %pt5; }.block {@extend %mt5;span {@extend %pt5;} } 復(fù)制代碼從輸出中可以看到,占位符的輸出中不包含占位符本身
.btn, .block {margin-top: 5px; }.btn, .block span {padding-top: 5px; } 復(fù)制代碼相同的實(shí)現(xiàn),我們再來看一下繼承
.mt5 {margin-top: 5px; } .pt5{padding-top: 5px; }.btn {@extend .mt5;@extend .pt5; }.block {@extend .mt5;span {@extend .pt5;} }繼承的輸出中包含了基類本身 .mt5, .btn, .block {margin-top: 5px; }.pt5, .btn, .block span {padding-top: 5px; } 復(fù)制代碼是不是感覺占位符很像繼承和@mixin的混合體。不支持參數(shù)傳遞的復(fù)用代碼塊(繼承),本身不出現(xiàn)在輸出中(@mixin)
混合宏 VS 繼承 VS 占位符
什么時(shí)候該使用它們中的某一個(gè)呢?在這里總結(jié)一下如何使用這幾個(gè)容易讓人弄混的概念
- 混合宏:不會自動合并相同的樣式文件,會造成代碼冗余,但是可以傳遞參數(shù)
- 繼承:會合并相同的代碼,通過組合選擇器輸出,但是不能傳遞參數(shù)
- 占位符:編譯出來的代碼和使用繼承基本上是一樣的,自是不會在代碼中出現(xiàn)占位符本身
占位符是獨(dú)立定義的,不調(diào)用的時(shí)候是不會在代碼充產(chǎn)生任何代碼。而繼承首先要保證有一個(gè)基類的存在,不管調(diào)用與不調(diào)用,積累的樣式都會出現(xiàn)在編譯出來的額CSS代碼中
下面的代碼幫助大家記憶三者的區(qū)別
//========= //混合宏寫法 @mixin mt($var){margin-top: $var; } .block {@include mt(4px);span {display:block;@include mt(3px);} } .header {color: orange;@include mt(5px);span{display:block;@include mt(5px);} } //混合宏寫法輸出 .block { margin-top: 4px; } .block span { display: block; margin-top: 3px; } .header { color: orange; margin-top: 5px; } .header span { display: block; margin-top: 5px; }//========= //繼承寫法 .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; }//========= //占位符 %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; } 復(fù)制代碼轉(zhuǎn)載于:https://juejin.im/post/5a31d22a51882510b2756325
總結(jié)
- 上一篇: 去电视视频广告再也不用购买vip去广告
- 下一篇: 从零开始netty学习笔记之BIO