前面的話
"CSS預處理器"(css preprocessor)的基本思想是,用一種專門的編程語言,進行網頁樣式設計,然后再編譯成正常的CSS文件。SASS是一種CSS的開發工具,提供了許多便利的寫法,大大節省了設計者的時間,使得CSS的開發,變得簡單和可維護。本文將詳細介紹sass的使用
定義
Sass是一門高于CSS的元語言,它能用來清晰地、結構化地描述文件樣式,有著比普通CSS更加強大的功能。
Sass能夠提供更簡潔、更優雅的語法,同時提供多種功能來創建可維護和管理的樣式表
【SASS和SCSS】
Sass和SCSS其實是同一種東西,我們平時都稱之為Sass,兩者之間不同之處有以下兩點:1、文件擴展名不同,Sass是以“.sass”后綴為擴展名,而SCSS是以“.scss”后綴為擴展名;2、語法書寫方式不同,Sass是以嚴格的縮進式語法規則來書寫,不帶大括號({})和分號(;),而SCSS的語法書寫和我們的CSS語法書寫方式非常類似
下面為Sass語法
$font-stack: Helvetica, sans-serif //定義變量
$primary-color: #333 //定義變量
body
font: 100% $font-stack
color: $primary-color
下面為SCSS語法
$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;
}
安裝
在Windows平臺下安裝Ruby需要先有Ruby安裝包。Ruby安裝文件
下載好后,可以按應用軟件安裝步驟進行安裝Ruby
在安裝過程中選擇第二個選項(若不選中,就會出現編譯時找不到Ruby環境的情況),如下圖所示
Ruby安裝完成后,在開始菜單中找到新安裝的Ruby,并啟動Ruby的Command控制面板(Start Command Prompt with Ruby)
安裝好Ruby之后,接下來就可以安裝Sass了。打開電腦的命令終端,輸入下面的命令:
gem install sass
【更新Sass】
在命令終端執行下列命令,可以將sass升級到最高版本
gem update sass
【卸載Sass】
在命令終端執行下列命令,可以卸載sass
gem uninstall sass
編譯
Sass的編譯包括以下幾種方法:命令編譯、GUI工具編譯和自動化編譯
[注意]在編譯sass時,常見的兩個錯誤是字符編碼錯誤(不支持gbk編碼)和路徑錯誤(不支持中文)
1、命令編譯
命令編譯是指使用電腦中的命令終端,通過輸入Sass指令來編譯Sass。這種編譯方式是最直接也是最簡單的一種方式
【單文件編譯】
sass <要編譯的Sass文件路徑>/style.scss:<要輸出CSS文件路徑>/style.css
【多文件編譯】
下面的命令表示將項目中“sass”文件夾中所有“.scss”(“.sass”)文件編譯成“.css”文件,并且將這些CSS文件都放在項目中“css”文件夾中
sass sass/:css/
在實際編譯過程中,會發現上面的命令只能一次性編譯。每次保存“.scss”文件之后,都得重新執行一次這樣的命令。如此操作太麻煩,其實還有一種方法,就是在編譯Sass時,開啟“watch”功能,這樣只要代碼進行任何修改,都能自動監測到代碼的變化,并且直接編譯出來:
[注意]冒號的左右兩側一定不要留空格
sass --watch <要編譯的Sass文件路徑>/style.scss:<要輸出CSS文件路徑>/style.css
sass --watch sass/test.scss:css/test.css
調試
使用chrome瀏覽器的sourcemap功能可以將本地的文件和服務器上的文件關聯起來。這樣,通過chrome的開發者工具調試網頁(如更改一個css屬性值)時,本地文件的內容也會相應地發生變化并保存。如果再使用sass的watch命令, 在調試sass文件時,就可以實時保存文件并通過瀏覽器看到效果
如下圖所示,點擊map to network resource,把本地文件關聯到服務器上相應文件。瀏覽器會智能地把項目目錄下的其他css文件和html文件和服務器上對應的文件都關聯起來
編譯風格
SASS提供四個編譯風格的選項:
nested:嵌套縮進的css代碼,它是默認值。
expanded:沒有縮進的、擴展的css代碼。
compact:簡潔格式的css代碼。
compressed:壓縮后的css代碼。
生產環境當中,一般使用最后一個選項
sass --style compressed test.sass test.css
2、GUI編譯
一般地,使用koala編譯器來對sass進行編譯
3、自動化編譯
使用grunt或gulp可以配置sass的編譯
下面以grunt為例,首先需要安裝sass插件
npm install grunt-contrib-sass --save-dev
然后,初始化grunt配置
grunt.initConfig({
sass: { // Task
dist: { // Target
options: { // Target options
style: 'expanded'
},
files: { // Dictionary of files
'main.css': 'main.scss', // 'destination': 'source'
'widgets.css': 'widgets.scss'
}
}
}
});
接下來,告訴grunt將使用該插件
grunt.loadNpmTasks('grunt-contrib-sass');
最后,告訴grunt當我們在終端中輸入grunt時需要做些什么
grunt.registerTask('default', ['sass']);
語法
數據類型
SassScript 支持六種主要的數據類型:
1、數字(例如 1.2、13、10px)
2、文本字符串,無論是否有引號(例如 "foo"、'bar'、baz)
3、顏色(例如 blue、#04a3f9、rgba(255, 0, 0, 0.5))
4、布爾值(例如 true、false)
5、空值(例如 null)
6、值列表,用空格或逗號分隔(例如 1.5em 1em 0 2em、Helvetica, Arial, sans-serif)
Sass還支持所有其他CSS屬性值類型,例如Unicode范圍和!important聲明。然而,它不會對這些類型做特殊處理。它們只會被當做不帶引號的字符串看待
注釋
sass有兩種注釋方式,一種是標準的css注釋方式/* */,另一種則是//雙斜桿形式的單行注釋,不過這種單行注釋不會輸入到CSS中
/*
*多行注釋
*/
body{
padding:5px;
}
//單行注釋
body{
padding:5px; //5px
}
變量
SASS的變量用法類似于php與css語法的結合,所有變量以$變量,變量名和變量值之間用冒號隔開。定義之后可以在全局范圍內使用
$blue : #1875e7;
div {
color : $blue;
}
如果變量需要鑲嵌在字符串之中,就必須需要寫在#{}之中
$side : left;
.rounded {
border-#{$side}-radius: 5px;
}
【默認變量】
sass的默認變量僅需要在值后面加上!default即可。sass的默認變量一般用來設置默認值,然后根據需求來覆蓋。覆蓋的方式也很簡單,只需要在默認變量之前重新聲明變量即可
//sass style
//-------------------------------
$baseLineHeight: 2;
$baseLineHeight: 1.5 !default;
body{
line-height: $baseLineHeight;
}
//css style
//-------------------------------
body{
line-height:2;
}
【特殊變量】
一般我們定義的變量都為屬性值,可直接使用,但是如果變量作為屬性或在某些特殊情況下(如嵌套在字符串中)等則必須要以#{$variables}形式使用
$borderDirection: top !default;
$baseFontSize: 12px !default;
//應用于class和屬性
.border-#{$borderDirection}{
border-#{$borderDirection}:1px solid #ccc;
}
//應用于復雜的屬性值
body{
font:#{$baseFontSize}/#{$baseLineHeight};
}
【全局及局部變量】
在選擇器、函數、混合宏...的里面定義的變量叫局部變量,它們的外面定義的變量為全局變量
//scss
$color: orange;
.block {
color: $color;//調用全局變量
}
em {
$color: red;//定義局部變量
a {
color: $color;//調用局部變量
}
}
span {
color: $color;//調用全局變量
}
//CSS
.block {
color: orange;
}
em a {
color: red;
}
span {
color: orange;
}
嵌套
選擇器嵌套提供了一個通過局部選擇器相互嵌套實現全局選擇的方法,Sass 的嵌套分為兩種:1、選擇器嵌套;2、屬性嵌套
【選擇器嵌套】
[注意]在sass嵌套嵌套中,可以使用&表示父元素選擇器
#top_nav{
line-height: 40px;
li{
float:left;
}
a{
display: block;
padding: 0 10px;
color: #fff;
&:hover{
color:#ddd;
}
}
}
//css style
//-------------------------------
#top_nav{
line-height: 40px;
}
#top_nav li{
float:left;
}
#top_nav a{
display: block;
padding: 0 10px;
color: #fff;
}
#top_nav a:hover{
color:#ddd;
}
【屬性嵌套】
CSS有一些屬性前綴相同,只是后綴不一樣,比如:border-top/border-right,與這個類似的還有 margin、padding、font等
[注意]border后面必須有冒號
//css
.box {
border-top: 1px solid red;
border-bottom: 1px solid green;
}
//scss
.box {
border: {
top: 1px solid red;
bottom: 1px solid green;
}
}
混合宏
混合宏是可以重用的代碼塊
在Sass中,使用“@mixin”來聲明一個混合宏
@mixin border-radius{
-webkit-border-radius: 5px;
border-radius: 5px;
}
可以使用@include
命令,來調用混合宏mixin
button {
@include border-radius;
}
mixin指定參數和缺省值
@mixin border-radius($radius:5px){
-webkit-border-radius: $radius;
border-radius: $radius;
}
div{
@include border-radius(10px);
}
Sass中的混合宏還提供更為復雜的情況,可以在大括號里面帶有邏輯關系
@mixin box-shadow($shadow...) {
@if length($shadow) >= 1 {
@include prefixer(box-shadow, $shadow);
} @else{
$shadow:0 0 4px rgba(0,0,0,.3);
@include prefixer(box-shadow, $shadow);
}
}
Sass在調用相同的混合宏時,并不能智能的將相同的樣式代碼塊合并在一起。這也是 Sass的混合宏最大的不足之處
【占位符】
占位符是介于混合宏和變量之間的一個功能
//SCSS
%mt5 {
margin-top: 5px;
}
%pt5{
padding-top: 5px;
}
.block {
@extend %mt5;
span {
@extend %pt5;
}
}
//CSS
.block {
margin-top: 5px;
}
.block span {
padding-top: 5px;
}
繼承
SASS允許一個選擇器,繼承另一個選擇器。比如,現有class1
.class1{
border: 1px solid black;
}
class2要繼承class1,就要使用@extend
命令
.class2{
@extend .class1;
font-size:120%;
}
Sass中的繼承,可以繼承類樣式塊中所有樣式代碼,而且編譯出來的CSS會將選擇器合并在一起,形成組合選擇器
//SCSS
.btn {
border: 1px solid #ccc;
padding: 6px 10px;
font-size: 14px;
}
.btn-primary {
background-color: #f36;
@extend .btn;
}
.btn-second {
background-color: orange;
@extend .btn;
}
//CSS
.btn, .btn-primary, .btn-second {
border: 1px solid #ccc;
padding: 6px 10px;
font-size: 14px;
}
.btn-primary {
background-color: #f36;
}
.btn-second {
background-clor: orange;
}
運算
SASS允許在代碼中使用算式
【注意事項】
1、100px * 2px會報錯,乘法應該寫成100px * 2
2、因為除號/在CSS中在特殊的含義,所以為了避免除法不生效,需要在外面添加一個小括號
3、類似于javascript,sass中的加法也有字符串連接的作用
$num: '1' + '1';
body{
top: 10px + 10px;//20
left: 10px - 10px;//0
right: 100px *2;//200
bottom: (100px/2);//50
width: $num;//11
}
語句
【條件語句】
@if
指令是一個SassScript,它可以根據條件來處理樣式塊,如果條件為true返回一個樣式塊,反之false返回另一個樣式塊。在Sass中除了@if
,還可以配合@else if
或@else
一起使用
//scss
@mixin blockOrHidden($boolean:true) {
@if $boolean {
display: block;
}
@else {
display: none;
}
}
.block {
@include blockOrHidden;
}
.hidden{
@include blockOrHidden(false);
}
//CSS:
.block {
display: block;
}
.hidden {
display: none;
}
【循環語句】
for循環
Sass中的for循環有兩種方式
@for $i from <start> through <end>
@for $i from <start> to <end>
這兩個的區別是關鍵字through表示包括end,而to則不包括end
//scss
@for $i from 1 through 3 {
.item-#{$i} { width: 2em * $i; }
}
//css
.item-1 {
width: 2em;
}
.item-2 {
width: 4em;
}
.item-3 {
width: 6em;
}
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;
}
each循環
//scss
$list: adam john wynn mason kuroir;
@mixin author-images {
@each $author in $list {
.photo-#{$author} {
background: url("/images/avatars/#{$author}.png") no-repeat;
}
}
}
.author-bio {
@include author-images;
}
//css
.author-bio .photo-adam {
background: url("/images/avatars/adam.png") no-repeat; }
.author-bio .photo-john {
background: url("/images/avatars/john.png") no-repeat; }
.author-bio .photo-wynn {
background: url("/images/avatars/wynn.png") no-repeat; }
.author-bio .photo-mason {
background: url("/images/avatars/mason.png") no-repeat; }
.author-bio .photo-kuroir {
background: url("/images/avatars/kuroir.png") no-repeat; }
函數
在命令終端開啟sass -i這個命令,相當于開啟Sass的函數計算
sass -i
【字符串函數】
unquote($string)
:刪除字符串中的引號
//SCSS
.test1 {
content: unquote('Hello Sass!') ;
}
.test3 {
content: unquote("I'm Web Designer");
}
.test5 {
content: unquote('"Hello Sass!"');
}
//css
.test1 {
content: Hello Sass!; }
.test3 {
content: I'm Web Designer; }
.test5 {
content: "Hello Sass!"; }
quote($string)
:給字符串添加引號,如果字符串自身帶有引號會統一換成雙引號""
//SCSS
.test1 {
content: quote('Hello Sass!');
}
.test2 {
content: quote("Hello Sass!");
}
.test3 {
content: quote(ImWebDesigner);
}
.test4 {
content: quote(' ');
}
//CSS
.test1 {
content: "Hello Sass!";
}
.test2 {
content: "Hello Sass!";
}
.test3 {
content: "ImWebDesigner";
}
.test4 {
content: "";
}
To-upper-case()
:將字符串小寫字母轉換成大寫字母
//SCSS
.test {
text: to-upper-case(aaaaa);
text: to-upper-case(aA-aAAA-aaa);
}
//CSS
.test {
text: AAAAA;
text: AA-AAAA-AAA;
}
To-lower-case()
:將字符串轉換成小寫字母
//SCSS
.test {
text: to-lower-case(AAAAA);
text: to-lower-case(aA-aAAA-aaa);
}
//CSS
.test {
text: aaaaa;
text: aa-aaaa-aaa;
}
【數字函數】
percentage($value)
:將一個不帶單位的數轉換成百分比值
//scss
.footer{
width : percentage(.2)
}
//css
.footer{
width : 20%
}
round()
將一個數四舍五入為一個最接近的整數
//scss
.footer1 {
width:round(15.8px)
}
.footer2 {
width:round(3.4em)
}
//css
.footer1 {
width:16px
}
.footer2 {
width:3em
}
ceil()
向上取整
//scss
.footer1 {
width:ceil(15.8px)
}
.footer2 {
width:ceil(3.4em)
}
//css
.footer1 {
width:16px
}
.footer2 {
width:4em
}
floor()
向下取整
//scss
.footer1 {
width:floor(15.8px)
}
.footer2 {
width:floor(3.4em)
}
//css
.footer1 {
width:15px
}
.footer2 {
width:3em
}
abs()
取絕對值
//scss
.footer1 {
width:abs(-15.8px)
}
.footer2 {
width:abs(3.4em)
}
//css
.footer1 {
width:15.7px
}
.footer2 {
width:3.4em
}
min()
取最小值,max()
取最大值
[注意]min()和max()都只可以比較相同單位的數值,否則會報錯
//scss
div{
height:max(10px,23px);
width:min(10px,23px);
}
//css
div{
height:23px;
width:10px;
}
random()
用來獲取一個隨機數
//scss
div{
color: rgba(200, 150, 40, random());
}
//css
div {
color: rgba(200, 150, 40, 0.57236);
}
【列表函數】
length()
用來返回一個列表中有幾個值。length()函數中的列表參數之間使用空格隔開,不能使用逗號,否則函數將會出錯
>> length(10px)
1
>> length(10px 20px (border 1px solid) 2em)
4
>> length(border 1px solid)
3
nth($list,$n)
用來指定列表中某個位置的值,nth()函數的起始值為1
>> nth(10px 20px 30px,1)
10px
>> nth((Helvetica,Arial,sans-serif),2)
"Arial"
>> nth((1px solid red) border-top green,1)
(1px "solid" #ff0000)
join()
用來將兩個列表連接合并成一個列表。不過join()只能將兩個列表連接成一個列表,如果直接連接兩個以上的列表將會報錯
>> join(10px 20px, 30px 40px)
(10px 20px 30px 40px)
>> join((blue,red),(#abc,#def))
(#0000ff, #ff0000, #aabbcc, #ddeeff)
>> join((blue,red),(#abc #def))
(#0000ff, #ff0000, #aabbcc, #ddeeff)
append()
用來將某個值插入到列表中,并且處于最末位
>> append(10px 20px ,30px)
(10px 20px 30px)
>> append((10px,20px),30px)
(10px, 20px, 30px)
>> append(green,red)
(#008000 #ff0000)
>> append(red,(green,blue))
(#ff0000 (#008000, #0000ff))
zip()
用于將多個列表值轉成一個多維的列表。在使用zip()函數時,每個單一的列表個數值必須是相同的,否則將會出錯
>> zip(1px 2px 3px,solid dashed dotted,green blue red)
((1px "solid" #008000), (2px "dashed" #0000ff), (3px "dotted" #ff0000))
index()
類似于索引一樣,用來找出某個值在列表中所處的位置。起始值是1,不是0
>> index(1px solid red, 1px)
1
>> index(1px solid red, solid)
2
>> index(1px solid red, red)
3
type-of()
主要用來判斷一個值是屬于什么類型
number為數值型,string為字符串型,bool為布爾型,color為顏色型
>> type-of(100)
"number"
>> type-of(100px)
"number"
>> type-of("asdf")
"string"
>> type-of(asdf)
"string"
>> type-of(true)
"bool"
>> type-of(false)
"bool"
>> type-of(#fff)
"color"
>> type-of(blue)
"color"
>> type-of(1 / 2 = 1)
"string"
unit()
用來獲取一個值所使用的單位,碰到復雜的計算時,其能根據運算得到一個“多單位組合”的值,不過只允許乘、除運算
>> unit(100)
""
>> unit(100px)
"px"
>> unit(20%)
"%"
>> unit(1em)
"em"
>> unit(10px * 3em)
"em*px"
>> unit(10px / 3em)
"px/em"
>> unit(10px * 2em / 3cm / 1rem)
"em/rem"
unitless()
用來判斷一個值是否帶有單位,如果不帶單位返回的值為 true,帶單位返回的值為 false
>> unitless(100)
true
>> unitless(100px)
false
>> unitless(100em)
false
>> unitless(100%)
false
>> unitless(1 /2 )
true
>> unitless(1 /2 + 2 )
true
>> unitless(1px /2 + 2 )
false
comparable()
用來判斷兩個數是否可以進行“加,減”以及“合并”。如果可以返回值為true,如果不可以返回值是false
>> comparable(2px,1%)
false
>> comparable(2px,1em)
false
>> comparable(2rem,1em)
false
>> comparable(2px,1cm)
true
>> comparable(2px,1mm)
true
Miscellaneous()
稱為三元條件函數。該函數有兩個值,當條件成立返回一種值,當條件不成立時返回另一種值
if($condition,$if-true,$if-false)
>> if(true,1px,2px)
1px
>> if(false,1px,2px)
2px
【顏色函數】
RGB顏色函數
rgb($red,$green,$blue)
根據紅、綠、藍三個值創建一個顏色
rgba($red,$green,$blue,$alpha)
根據紅、綠、藍和透明度值創建一個顏色
除了與CSS相同的rgba()格式外,sass中的rgba()還支持rgba(\(color,\)alpha)的格式。在實際工作中,如果在已知顏色的情況下,不改變顏色只加透明度,這個函數就能起到效果了
.overlayout{
background-color:rgba(#773,0.5);
}
red($color)
從一個顏色中獲取其中紅色值
green($color)
從一個顏色中獲取其中綠色值
blue($color)
從一個顏色中獲取其中藍色值
mix($color-1,$color-2,[$weight])
把兩種顏色混合在一起。$color-1
和$color-2
指需要合并的顏色,顏色可以是任何表達式,也可以是顏色變量
$weight
為第一個顏色合并所占的比例(權重),默認值為50%,其取值范圍是0~1之間。它是由每個RGB的百分比來衡量的,當然透明度也會有一定的權重。默認的比例是50%,這意味著兩個顏色各占一半,如果指定的比例是25%,這意味著第一個顏色所占比例為25%,第二個顏色所占比例為75%
mix(#f00, #00f) => #7f007f
mix(#f00, #00f, 25%) => #3f00bf
mix(rgba(255, 0, 0, 0.5), #00f) => rgba(63, 0, 191, 0.75)
HSL顏色函數
hsl($hue,$saturation,$lightness)
通過色相(hue)、飽和度(saturation)和亮度(lightness)的值創建一個顏色
hsla($hue,$saturation,$lightness,$alpha)
通過色相(hue)、飽和度(saturation)、亮度(lightness)和透明(alpha)的值創建一個顏色
hue($color)
從一個顏色中獲取色相(hue)值
saturation($color)
從一個顏色中獲取飽和度(saturation)值
lightness($color)
從一個顏色中獲取亮度(lightness)值
adjust-hue($color,$degrees)
通過改變一個顏色的色相值,創建一個新的顏色。色相是色彩的首要特征,是區別各種不同色彩的最準確的標準。事實上任何黑白灰以外的顏色都有色相的屬性,而色相也就是由原色、間色和復色來構成的
darken($color,$amount)
通過改變顏色的亮度值,讓顏色變暗,創建一個新的顏色
lighten($color,$amount)
通過改變顏色的亮度值,讓顏色變亮,創建一個新的顏色
lighten()和darken()兩個函數都是圍繞顏色的亮度值做調整的,其中lighten()函數會讓顏色變得更亮,與之相反的darken()函數會讓顏色變得更暗。這個亮度值可以是0~1之間,不過常用的一般都在3%~20%之間
[注意]當顏色亮度值接近或大于100%,顏色會變成白色;反之顏色亮度值接近或小于0時,顏色會變成黑色
//SCSS
$baseColor: #ad141e;
.lighten {
background: lighten($baseColor,10%);
}
.darken{
background: darken($baseColor,10%);
}
//CSS
.lighten {
background: #db1926;
}
.darken {
background: #7f0f16;
}
saturate($color,$amount)
通過改變顏色的飽和度值,讓顏色更飽和,從而創建一個新的顏色。飽和度是指色彩的鮮艷程度,也稱色彩的純度
desaturate($color,$amount)
通過改變顏色的飽和度值,讓顏色更少的飽和,從而創建出一個新的顏色
saturate()、desaturate()這兩個函數是通過改變顏色的飽和度來得到一個新的顏色,他們和前面介紹的修改亮度得到新顏色的方法非常相似
grayscale($color)
函數會顏色的飽和度值直接調至0%,所以此函數與desaturate($color,100%)所起的功能是一樣的。一般這個函數能將彩色顏色轉換成不同程度的灰色將一個顏色變成灰色
//SCSS
$baseColor: #ad141e;
.grayscale {
background: grayscale($baseColor);
}
.desaturate {
background: desaturate($baseColor,100%);
}
//CSS
.grayscale {
background: #616161;
}
.desaturate {
background: #616161;
}
complement($color)
返回一個補充色,相當于adjust-hue($color,180deg)
invert($color)
返回一個反相色,紅、綠、藍色值倒過來,而透明度不變
>> hsl(200,30%,60%) //通過h200,s30%,l60%創建一個顏色
#7aa3b8
>> hsla(200,30%,60%,.8)//通過h200,s30%,l60%,a80%創建一個顏色
rgba(122, 163, 184, 0.8)
>> hue(#7ab)//得到#7ab顏色的色相值
195deg
>> saturation(#7ab)//得到#7ab顏色的飽和度值
33.33333%
>> lightness(#7ab)//得到#7ab顏色的亮度值
60%
>> adjust-hue(#f36,150deg) //改變#f36顏色的色相值為150deg
#33ff66
>> lighten(#f36,50%) //把#f36顏色亮度提高50%
#ffffff
>> darken(#f36,50%) //把#f36顏色亮度降低50%
#33000d
>> saturate(#f36,50%) //把#f36顏色飽和度提高50%
#ff3366
>> desaturate(#f36,50%) //把#f36顏色飽和度降低50%
#cc667f
>> grayscale(#f36) //把#f36顏色變成灰色
#999999
>> complement(#f36)
#33ffcc
透明度顏色函數
在CSS中除了可以使用rgba、hsla和transform來控制顏色透明度之外,還可以使用opacity來控制,只不過前兩者只是針對顏色上的透明通道做處理,而后者是控制整個元素的透明度
alphpa()
和opacity()
很簡單,與前面介紹的red()、green()等函數很類似。函數的主要功能是用來獲取一個顏色的透明度值。如果顏色沒有特別指定透明度,那么這兩個函數得到的值都會是1
>> alpha(red)
1
>> alpha(rgba(red,.8))
0.8
>> opacity(red)
1
>> opacity(rgba(red,.8))
0.8
opacify()
和fade-in()
是用來對已有顏色的透明度做一個加法運算,會讓顏色更加不透明。其接受兩個參數,第一個參數是原始顏色,第二個參數是需要增加的透明度值,其取值范圍主要是在0~1之間。當透明度值增加到大于1時,會以1計算,表示顏色不具有任何透明度
>> opacify(rgba(22,34,235,.6),.2)
rgba(22, 34, 235, 0.8)
>> opacify(rgba(22,34,235,.6),.5)
#1622eb
>> opacify(hsla(22,34%,23%,.6),.15)
rgba(79, 53, 39, 0.75)
>> opacify(hsla(22,34%,23%,.6),.415)
#4f3527
>> opacify(red,.15)
#ff0000
>> opacify(#89adde,.15)
#89adde
>> fade-in(rgba(23,34,34,.5),.15)
rgba(23, 34, 34, 0.65)
>> fade-in(rgba(23,34,34,.5),.615)
#172222
transparentize()
和fade-out()
所起作用剛好與opacify()和fade-in()函數相反,讓顏色更加的透明。這兩個函數會讓透明值做減法運算,當計算出來的結果小于0時會以0計算,表示全透明
>> transparentize(red,.5)
rgba(255, 0, 0, 0.5)
>> transparentize(#fde,.9)
rgba(255, 221, 238, 0.1)
>> transparentize(rgba(98,233,124,.3),.11)
rgba(98, 233, 124, 0.19)
>> transparentize(rgba(98,233,124,.3),.51)
rgba(98, 233, 124, 0)
>> fade-out(red,.9)
rgba(255, 0, 0, 0.1)
>> fade-out(hsla(98,6%,23%,.5),.1)
rgba(58, 62, 55, 0.4)
>> fade-out(hsla(98,6%,23%,.5),.6)
rgba(58, 62, 55, 0)
數組
Sass的map常常被稱為數據地圖,也有人稱其為數組,因為它總是以key:value成對的出現,但其更像是一個JSON數據
$map: (
key1: value1,
key2: value2,
key3: value3
)
首先有一個類似于Sass的變量一樣,用個$加上命名空間來聲明map。后面緊接是一個小括號(),將數據以key:value的形式賦予,其中key和value是成對出現,并且每對之間使用逗號(,)分隔,其中最后一組后面沒有逗號。其中鍵key是用來查找相關聯的值value。使用map可以很容易收集鍵的值和動態插入
在Sass中常用下面的方式定義變量
$default-color: #fff !default;
$primary-color: #22ae39 !default;
使用map可以更好的進行管理
$color: (
default: #fff,
primary: #22ae39
);
如果哪天需要新增加顏色變量值,在map中可以非常方便的添加
$color: (
default: #fff,
primary: #22ae39,
negative: #d9534f
);
對于map,還可以讓map嵌套map。其實就是map的某一個key當成map,里面可以繼續放一對或者多對key:value
$map: (
key1: value1,
key2: (
key-1: value-1,
key-2: value-2,
),
key3: value3
);
map嵌套的實用性強,在換膚項目中,每一套皮膚對應的顏色蠻多的,使用map嵌套來管理顏色的變量就非常的有條理性,便于維護與管理
$theme-color: (
default: (
bgcolor: #fff,
text-color: #444,
link-color: #39f
),
primary:(
bgcolor: #000,
text-color:#fff,
link-color: #93f
),
negative: (
bgcolor: #f36,
text-color: #fefefe,
link-color: #d4e
)
);
為了方便的操作map,在Sass中map自身帶了七個函數
map-get($map,$key)
用來根據$key
參數,返回$key
在$map
中對應的value值。如果$key
不存在$map
中,將返回null值。該函數包含兩個參數:$map
表示定義好的map;$key
表示需要遍歷的key
//scss
$social-colors: (
dribble: #ea4c89,
facebook: #3b5998,
github: #171515,
google: #db4437,
twitter: #55acee
);
.btn-dribble{
color: map-get($social-colors,facebook);
}
//css
.btn-dribble {
color: #3b5998;
}
如果是多重數組,可以嵌套使用map-get()
函數來獲取值
//scss
$theme-color: (
default: (
bgcolor: #fff,
text-color: #444,
link-color: #39f
),
primary:(
bgcolor: #000,
text-color:#fff,
link-color: #93f
),
negative: (
bgcolor: #f36,
text-color: #fefefe,
link-color: #d4e
)
);
h1{
color:map-get(map-get($theme-color,default),text-color);
}
//css
h1 {
color: #444;
}
map-has-key($map,$key)
用來判斷map中是否存在參數中的key,如果存在則返回true,否則返回false
//scss
$social-colors: (
dribble: #ea4c89,
facebook: #3b5998,
github: #171515,
google: #db4437,
twitter: #55acee
);
@if map-has-key($social-colors,facebook){
.btn-facebook {
color: map-get($social-colors,facebook);
}
} @else {
@warn "No color found for faceboo in $social-colors map. Property ommitted."
}
//css
.btn-fackbook{
color: #3b5998;
}
如果使用上面的寫法,每獲取一個key都需要寫一個if語句,其實可以自定義函數來解決這個問題
//scss
$social-colors: (
dribble: #ea4c89,
facebook: #3b5998,
github: #171515,
google: #db4437,
twitter: #55acee
);
@function colors($color){
@if not map-has-key($social-colors,$color){
@warn "No color found for `#{$color}` in $social-colors map. Property omitted.";
}
@return map-get($social-colors,$color);
}
.btn-dribble {
color: colors(dribble);
}
.btn-facebook {
color: colors(facebook);
}
.btn-github {
color: colors(github);
}
.btn-google {
color: colors(google);
}
.btn-twitter {
color: colors(twitter);
}
.btn-weibo {
color: colors(weibo);
}
//css
.btn-dribble {
color: #ea4c89;
}
.btn-facebook {
color: #3b5998;
}
.btn-github {
color: #171515;
}
.btn-google {
color: #db4437;
}
.btn-twitter {
color: #55acee;
}
用each()循環來減少重復
@each $social-network,$social-color in $social-colors {
.btn-#{$social-network} {
color: colors($social-network);
}
}
map-keys($map)
將返回$map
中的所有key。這些值賦予給一個變量,就是一個列表
//scss
$social-colors: (
dribble: #ea4c89,
facebook: #3b5998,
github: #171515,
google: #db4437,
twitter: #55acee
);
@each $i in map-keys($social-colors){
.c-#{$i}{
color: map-get($social-colors,$i);
}
};
//css
.c-dribble {
color: #ea4c89;
}
.c-facebook {
color: #3b5998;
}
.c-github {
color: #171515;
}
.c-google {
color: #db4437;
}
.c-twitter {
color: #55acee;
}
map-values($map)
類似于map-keys($map)
功能,不同的是,map-values($map)
得到的是鍵值,而map-keys($map)
得到的是鍵名
//scss
$social-colors: (
dribble: #ea4c89,
facebook: #3b5998,
github: #171515,
google: #db4437,
twitter: #55acee
);
@each $val in map-values($social-colors){
.c-#{$val}{
color: $val;
}
};
//css
.c-dribble {
color: #ea4c89;
}
.c-facebook {
color: #3b5998;
}
.c-github {
color: #171515;
}
.c-google {
color: #db4437;
}
.c-twitter {
color: #55acee;
}
map-merge($map1,$map2)
用于將$map1
和$map2
合并,然后得到一個新的$map
。如果$map1
和$map2
中有相同的$key
名,那么將$map2
中的$key
會取代$map1
中的$key
$color: (
text: #f36,
link: #f63,
border: #ddd,
backround: #fff
);
$typo:(
font-size: 12px,
line-height: 1.6,
border: #ccc,
background: #000
);
$newmap: map-merge($color,$typo);
$newmap:(
text: #f36,
link: #f63,
font-size: 12px,
line-height: 1.6,
border: #ccc,
background: #000
);
map-remove($map,$key)
用來刪除當前map中的某一個key,從而得到一個新的map。其返回的值還是一個map。他并不能直接從一個map中刪除另一個map,僅能通過刪除map中的某個key得到新map。如果刪除的key并不存在于map中,那么map-remove()
函數返回的新map和以前的map一樣
$social-colors: (
dribble: #ea4c89,
facebook: #3b5998,
github: #171515,
google: #db4437,
twitter: #55acee
);
$map:map-remove($social-colors,dribble);
$map:(
facebook: #3b5998,
github: #171515,
google: #db4437,
twitter: #55acee
);
keywords($args)
是一個動態創建map的函數。可以通過混合宏或函數的參數變創建map。參數也是成對出現,其中$args
變成key(會自動去掉$
符號),而$args
對應的值就是value
@mixin map($args...){
@debug keywords($args);
}
@include map(
$dribble: #ea4c89,
$facebook: #3b5998,
$github: #171515,
$google: #db4437,
$twitter: #55acee
);
在命令終端可以看到一個@debug信息:
DEBUG: (dribble: #ea4c89, facebook: #3b5998, github: #171515, google: #db4437, twitter: #55acee)
指令
Sass支持所有CSS3的@
規則,以及一些Sass專屬的規則,也被稱為“指令(directives)”
【@import】
Sass擴展了CSS的@import
規則,讓它能夠引入SCSS和Sass文件。所有引入的SCSS和Sass文件都會被合并并輸出一個單一的CSS文件。另外,被導入的文件中所定義的變量或mixins都可以在主文件中使用
Sass會在當前目錄下尋找其他Sass文件,如果是Rack、Rails或Merb環境中則是Sass文件目錄。也可以通過:load_paths選項或者在命令行中使用--load-path選項來指定額外的搜索目錄
@import
根據文件名引入。默認情況下,它會尋找Sass文件并直接引入,但是,在少數幾種情況下,它會被編譯成CSS的@import
規則,包括以下幾種情況:如果文件的擴展名是.css;如果文件名以http://開頭;如果文件名是url();如果@import
包含了任何媒體查詢(mediaqueries)
如果上述情況都沒有出現,并且擴展名是.scss或.sass,該名稱的Sass或SCSS文件就會被引入。如果沒有擴展名,Sass將試著找出具有.scss或.sass擴展名的同名文件并將其引入
【@media】
Sass中的@media
指令和CSS的使用規則一樣的簡單,但它有另外一個功能,可以嵌套在CSS規則中。有點類似JS的冒泡功能一樣,如果在樣式中使用@media
指令,它將冒泡到外面
//scss
.sidebar {
width: 300px;
@media screen and (orientation: landscape) {
width: 500px;
}
}
//css
.sidebar {
width: 300px; }
@media screen and (orientation: landscape) {
.sidebar {
width: 500px; } }
【@extend】
Sass中的@extend
是用來擴展選擇器或占位符
//scss
.error {
border: 1px #f00;
background-color: #fdd;
}
.error.intrusion {
background-image: url("/image/hacked.png");
}
.seriousError {
@extend .error;
border-width: 3px;
}
//css
.error, .seriousError {
border: 1px #f00;
background-color: #fdd; }
.error.intrusion, .seriousError.intrusion {
background-image: url("/image/hacked.png"); }
.seriousError {
border-width: 3px; }
【@at-root】
@at-root
從字面上解釋就是跳出根元素。當選擇器嵌套多層之后,想讓某個選擇器跳出,此時就可以使用@at-root
//scss
.a {
color: red;
.b {
color: orange;
.c {
color: yellow;
@at-root .d {
color: green;
}
}
}
}
//css
.a {
color: red;
}
.a .b {
color: orange;
}
.a .b .c {
color: yellow;
}
.d {
color: green;
}
【@debug】
@debug
在Sass中是用來調試的,當在Sass的源碼中使用了@debug
指令之后,Sass代碼在編譯出錯時,在命令終端會輸出設置的提示Bug:
@debug 10em + 12em;
會輸出:
Line 1 DEBUG: 22em
【@error、@warn】
@error
和@warn
、@debug
功能類似,可類比于javascript中的console.error()、console.warn()和console.debug()
實例
下面來使用SCSS來實現一個七色卡片的效果,如下圖所示
首先,要了解顏色模式除了RGB模式,還有HSL模式
h:色調(hue)可以為任意整數。0(或360或-360)表示紅色,60表示黃色,120表示綠色,180表示青色,240表示藍色,300表示洋紅(當h值大于360時,實際的值等于該值模360后的值)
s:飽和度(saturation),就是指顏色的深淺度和鮮艷程度。取0-100%范圍的值,其中0表示灰度(沒有該顏色),100%表示飽和度最高(顏色最鮮艷)
l:亮度(lightness),取0-100%范圍的值,其中0表示最暗(黑色),100%表示最亮(白色)
[注意]關于CSS中HSL模式的詳細信息移步至此
由于對色彩知識并沒有深入的了解,就以圖片表觀上從左到右亮度逐漸變小為依據,來寫CSS
下面來分析圖片,從上到下分別是紅、橙、黃、藍、綠、紫、黑七種顏色,共7行。每行都有21列,從左到右,亮度逐漸變小。最左列為純白,最右列為純黑。所以,可以以最中心列的顏色為起點,向左10列,每列亮度增加10%,最左列亮度為100%。向右10列,每列亮度減小10%,最右列亮度為0%
使用量圖工具,量得每一行中心列的顏色值從上到下分別為:#e02744、#ec8a00、#fae200、#91de00、#47c9f2、#a500fe、#848484
下面要使用SASS中關于亮度改變的函數:darken()讓顏色變暗和lighten()讓顏色變亮
在lighten()函數中,參數amount為50%,則為全白。所以,第1到第10列的參數amount為從50%到5%;類似地,在darken()函數中,參數amount為50%,則為全黑。所以,第12到第21列的參數amount為從5%到50%
【HTML代碼】
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" href="css/test.css">
</head>
<body>
<div class="box">
<ul class="red">
<li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li>
</ul>
<ul class="orange">
<li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li>
</ul>
<ul class="yellow">
<li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li>
</ul>
<ul class="green">
<li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li>
</ul>
<ul class="blue">
<li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li>
</ul>
<ul class="purple">
<li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li>
</ul>
<ul class="grey">
<li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li>
</ul>
</div>
</body>
</html>
【SASS代碼】
body{margin: 0}
ul{margin: 0;padding: 0;list-style:none;overflow: hidden}
li{float:left;height: 30px;width: 20px;}
//定義colorMap用于儲存每一行中間列的顏色值
$colorMap: (
red: #e02744,
orange: #ec8a00,
yellow: #fae200,
green: #91de00,
blue: #47c9f2,
purple: #a500fe,
grey: #848484
);
//為一行中的每個元素設置背景顏色
@mixin changelightness($color){
@for $index from 1 through 21 {
//從第一列到第十列,亮度增大值由50%變化到5%
@if($index < 11){
//amount表示當前列的亮度
$amount: percentage((11-$index)/20);
li:nth-child(#{$index}) {
background-color: lighten($color,$amount);
}
}
//第十一列為中心列,以測量值賦值
@if($index == 11){
li:nth-child(#{$index}){
background-color: $color;
}
}
//從第十二列到第二十一列,亮度減小值由5%變化到50%
@if($index > 11){
$amount: percentage(($index - 11)/20);
li:nth-child(#{$index}){
background-color: darken($color,$amount);
}
}
}
}
//通過forEach循環為每一行(也就是HTML結構中的每一個ul)添加樣式
@each $index in map-keys($colorMap){
.#{$index}{
@include changelightness(map-get($colorMap,$index));
}
}
【實際效果】
文章列表
留言列表