要了解sass或less的變量,有必要先了解下js的變量定義,先來一段js的代碼:php
var a = 1; (function(){ a = 5; })(); console.log(a);//5
上面這段代碼,匿名函數裏面的a由於沒有使用var關鍵字來定義,因此當咱們在函數外打印a的時候,獲得的是5,改變了一開始定義的1css
var a = 1; (function(){ var a = 5; })(); console.log(a);//1
而這段代碼,匿名函數裏面的a使用了var關鍵字來定義,因此當咱們在函數外打印a的時候,獲得的是1,一開始定義的值。java
若是你明白了上面兩個的區別,那下面就好辦了,若是你尚未明白,那麼建議先去看下js的變量申明。 也許你如今已經看出眉目了,其實sass的變量設計用的是上面兩段代碼中的第一段思想,即在局部不使用var來申明,而less用的是第二段思想,即局部使用var來申明,這就是不少人所說的爲何sass沒有局部變量。咱們來兩段代碼測試下:css3
sass版git
$color:red; p{ $color:blue; color:$color;//blue } a{ color:$color;//blue }
less版github
@color:red; p{ @color:blue; color:@color;//blue } a{ color:@color;//red }
簡單總結下:若是全局申明瞭一個變量a,sass中若是使用到局部中是屬於改變a的值,因此後來全部的都是改變以後的值;而less中使用到局部變量則屬於在局部從新定義a的值,不影響其餘地方。說到底,其實sass和less的變量其實都是js變量的表現形式,二者都有其科學性,只是設計思路不一樣而已。web
固然說到這裏,可能有人會說了,那sass就沒有局部變量嘍。其實否則,正確的說法應該是:在有全局變量的狀況下,sass是沒有局部變量的。意思是若是要看到sass的局部變量,請不要設置全局變量。代碼爲證:sass
p{ $color:blue; color:$color;//blue } a{ color:$color;//$color未定義 }
這是一個沒有定義全局變量$color的例子,上面的p元素的color爲blue,而a裏面就會報錯由於$color沒定義,它沒有獲取到p元素裏面定義的那個$color變量,這證實了其實sass一樣存在局部變量,只是這個前提是得沒有全局變量。less
相信到這裏,你們應該對sass的變量有所瞭解,不至於那麼迷惑吧。下面咱們再來兩段代碼:函數
p{ $color:blue; color:$color;//blue a{ color:$color;//blue } }
這一段代碼中,a嵌套在p中,而後在p元素中定義了$color這個變量,a裏面是能夠訪問到$color變量的。
p{ $color:blue; color:$color;//blue a{ $color:red; color:$color;//red } background-color:$color;//red span{ color:$color;//red } } div{ color:$color;//$color未定義 }
估計這裏有人迷惑了,咱們來分析下吧:由於sass的代碼是從上到下解析的,因此這段代碼執行到p的color值的時候顏色是上面的blue色,而後因爲咱們在a中又改變了$color的值爲紅色,因此後面全部p元素範圍內用到$color這個變量的都爲紅色,這反應到咱們後來的bgcolor和span的color上面,而p元素以外仍是未定義。
這裏吐個槽吧,其實我的以爲正是因爲這個,使得開發sass的當心定義變量,以免污染;而less呢卻恰好相反,估計到時候就是全局局部滿天飛的狀況,代碼一團糟。你想選擇哪一種呢?
關於sass的所有變量和局部變量就說到這,既然這篇文章的標題說了是sass變量揭祕,光這全局變量和局部變量確定是知足不了你們的胃口的,下面咱們繼續說下sass變量的另外一個創新點,變量默認值。
可能不少人對這個不是很熟悉,或者以爲這個其實就是個幌子,掛羊頭賣狗肉的傢伙。其實否則,它的來頭可不小,並且是很是的科學,我是佩服的五體投地,由於它從根本上解決了困擾我多年的css組件化開發。簡單來兩段比較的代碼:
無!default
$color:red; $color:blue; p{ color:$color;//blue }
有!default
$color:red; $color:blue !default; p{ color:$color;//red }
上面說了,sass編譯css是從上到下的,後面會覆蓋前面的,因此第一段無!default的解析的是blue,而第二段代碼因爲有了!default,打破了這個規則,使用了前面定義的red。有意思吧,固然這樣的使用是體現不了它偉大的價值的。
簡單介紹下它的做用吧:假設變量申明帶有!default,那麼若是在此申明以前沒有這個變量的申明,則用這個值,反之若是以前有申明,則用申明的值。固然若是你先!default申明,而後再申明一次,那就沒什麼意思了,這就是基本的變量覆蓋,第一次申明的有無!default都同樣。因此你要區分這兩種狀況:
//第一種,使用默認值 //變量申明帶有!default,可是以前沒有這個變量的申明
$color:blue !default; p{ color:$color;//blue }
//第二種,使用前面定義的值
$color:red;
//變量申明帶有!default,可是前面還有這個變量的申明
$color:blue !default; p{ color:$color;//red }
//第三種錯誤的用法,先!default申明
$color:red !default; $color:blue;
上面的第三種錯誤用法其實和下面的這個覆蓋寫法是同樣同樣的:
//覆蓋寫法
$color:red;
$color:blue;
能一口氣看到這裏的,應該有點時間,建議簡單活動下,搖搖腦殼,伸伸懶腰,由於下面的更加精彩。
其實長久以來,css之因此不能組件化開發,有兩大緣由:第一個是@import的樣式不能合併在一個文件中(這裏排除使用壓縮工具來合併);第二個問題就是這裏說到的變量問題了。感謝sass幫咱們全解決了,大笑三聲。
如今假設咱們有個scss文件,這裏暫且叫作_imgstyle.scss
,代碼以下:
// 變量 //--------------------------------- $imgStyleBorder: 1px solid #ccc !default; $imgStylePadding: 2px !default; $imgStyleRadius: 8px !default; // mixin //--------------------------------- @mixin img-border($border:$imgStyleBorder,$padding:$imgStylePadding){ border: $border; padding: $padding; } @mixin img-rounded($radius:$imgStyleRadius){ border-radius:$radius; } //樣式 //--------------------------------- .img-border{ @include img-border; } .img-rounded{ @include img-rounded; }
接下來咱們要在style.scss
這個文件裏面調用_imgstyle.scss
,代碼以下:
//導入_imgstyle.scss @import 'imgstyle';
如今問題來了,若是咱們對默認的padding爲2px不滿意,要改成5px,咱們有以下方法:
方法一:從新覆寫
//導入_imgstyle.scss @import 'imgstyle'; .img-border{ padding:5px; }
解析成的css:
.img-border { border: 1px solid #cccccc; padding: 2px; } .img-rounded { border-radius: 8px; } .img-border { padding: 5px; }
方法二:改變@include的參數
//導入_imgstyle.scss @import 'imgstyle'; .img-border{ @include img-border($imgStyleBorder,5px); }
解析成的css:
.img-border { border: 1px solid #cccccc; padding: 2px; } .img-rounded { border-radius: 8px; } .img-border { border: 1px solid #cccccc; padding: 5px; }
顯而易見,上面的方法都會產生重複的代碼,不科學啊。固然這時候可能有人會說了,你腦子浸水了唄,直接在_imgstyle.scss
文件中,修改$imgStyleBorder
爲5px不就得了。固然若是你要的是每一個項目使用這個樣式的時候都拷貝一份這個,而後打開把變量修改爲你要的值,那麼我只好認可我腦子浸水了,不只腦子浸水,還得吐血了。
如今請上面那些山寨土鱉方法閃一邊去,該咱們的!default出場了,廢話少說,上代碼:
//申明$imgStylePadding爲5px $imgStylePadding: 5px; //導入_imgstyle.scss @import 'imgstyle'; 解析成的css: .img-border { border: 1px solid #cccccc; padding: 5px; } .img-rounded { border-radius: 8px; }
無須去源文件中修改,且解析出來無重複代碼,完美!這纔是!default的價值,這爲組件式開發,更改調用組件裏面的變量的值帶來了完全的變化。若是less真沒有這個變量的默認值的話,那less的同窗們估計得傷心死了。
重量級的都介紹完了,下面把其餘的一些小羅羅也簡單介紹下吧。
在css3出現之前,你是絕對沒有看到過的,由於它就是爲css3而設計的。css3在給css帶來翻天覆地的變化以外,也給sass的@mixin傳遞參數帶來糾結了。通常來講咱們的@mixin傳遞的參數是以,
來分隔的,可是css3的一些屬性能夠設置多個值,而且多個值以,
分開,如box-shadow:0 0 3px rgba(0,0,0,0.3),inset 0 0 3px rgba(255,255,255,0.3);
這讓@mixin如何給box-shadow傳遞參數啊。因此這種變量後面加...
的變量就出現了。
@mixin box-shadow($shadow...){ -webkit-box-shadow:$shadow; -moz-box-shadow:$shadow; box-shadow:$shadow; }
這樣就完美解決了這個需求了,漂亮吧哈哈。注意這種變量加...
的方式只出如今傳遞參數中,你能夠看到上面的大括號裏面的變量都是沒有...
。除了box-shadow,gradient也能夠用,反正能使用多個值的屬性裏面均可以用。
#{}
包裹通常來講,咱們設置的變量都是用於屬性值的,而若是用在屬性或者選擇器上,就得以#{}
包裹起來了。
$btnClass: btn !default; $borderDirection: top !default; .#{$btnClass}{ border-#{$borderDirection}:1px solid #ccc; } 解析成的css: .btn{ border-top:1px solid #ccc; }
其實這個仍是很實用的,把多個相關的值寫在一個變量裏,而後經過nth($var,index)
來獲取第幾個值。
$linkColor: red blue !default; a{ color:nth($linkColor,1); &:hover{ color:nth($linkColor,2); } } 解析成的css: a { color: red; } a:hover { color: blue; }
關於sass變量揭祕到此爲止。若是已經開始使用sass了,歡迎試用sassCore這個庫。