Sass 函數
1. 前言
本節教程來講解 Sass 中的函數,這在 Sass 中是比較強大的一個功能,同時使用場景和語法也比較多,所以本節內容篇幅較長,但你一定要好好學習, Sass 函數很重要!在 Sass 中函數中幾乎可以用到前面你學的所有章節的內容,所以說函數包括萬象同時功能也非常強大,本節我們將詳細講解 Sass 中各種函數的功能和用法。
2. 什么是函數?
函數是一段可以被另外的程序或代碼調用的“子程序”,一個函數由稱為函數體的一系列代碼語句組成,并且函數也可以接收值,在大多數語言中函數都是這樣的,Sass 中的函數也是一樣。
3. Sass 函數簡介
Sass 為我們提供了很多內置模塊,其中就包含了很多函數(包括一些指令),我們可以通過 @use 去加載它們,然后我們就可以調用了,當然還有一些函數可以直接在 CSS 語句中調用,在 Sass 中常用的函數有:
- 字符串函數
- 數字函數
- 列表函數
- Introspection函數
- 條件函數
- Map 函數
- 顏色函數
上面這些函數為我們提供了強大而豐富的功能來更高效地編寫樣式,下面我們來詳細講解 Sass 函數。
4. 語法示例
我們先來看一段 Sass 函數的代碼來直觀感受一下:
$list: [1,2,4,5];
$string: 'string';
$substring: 'str';
.box {
font-size:length($list); // 列表函數
font: quote($string); // 字符串函數
font: str-index($string, $substring); // 字符串函數
color: adjust-hue(#6b717f, 60deg); // 顏色函數
border-width: ceil(4.2); // 數字函數
width: percentage(.7); // 數字函數
font: type-of(#676767); // Introspection函數
}
上面的示例代碼中我們舉了幾種函數的例子,在實際開發中并不會這么寫,這里把它們作為屬性值只是為了直觀的展示,所以先不要在意屬性;可以從上面的例子看出,函數的使用就像 javascript 中的函數一樣,通過函數名來調用,然后在括號中傳參,最后會得到函數的返回結果,那上面示例中這些函數的返回結果是什么呢?轉換為 CSS 的代碼如下:
.box {
font-size: 4;
font: "string";
font: 1;
color: #796b7f;
border-width: 5;
width: 70%;
font: color;
}
可以看到上面轉換為 CSS 的代碼中的屬性值就是函數的返回結果,可能在這里你還不是很懂,沒關系下面我們開始詳細講解 Sass 提供的這些函數!在這里你要知道 Sass 中的函數也是通過函數名調用并傳參,最后 Sass 會為你返回函數的執行結果。
5. 使用場景
在上面的語法示例中你已經感受了 Sass 函數,下面我們開始詳細的來講解它。
5.1 字符串函數
字符串函數主要提供了字符串類型的相關操作,就像在 javascript 中一樣,Sass 提供的字符串函數可以獲取字符串的長度,字符串的下標以及字符串中的大小寫字母轉換等等。
5.1.1 quote ($ string) 和 unquote($ string)
這兩個函數我們放在一起講解,它們都接收 1 個參數,參數是字符串類型,quote($string) 函數的返回結果是 以帶引號的形式返回你傳入的字符串,反之 unquote($string) 函數的返回結果是以不帶引號的形式返回你傳入的字符串,我們舉例看下:
string.quote(aaa) //=> "aaa"
unquote("bbb") //=> bbb
5.1.2 str-index($string, $substring)
str-index($string, $substring) 函數接收 2 個參數,返回 $substring 在 $string 中的第一次出現的索引,如果在 $string 中不包含 $substring 則返回 null ,我們舉例看下:
str-index("abcde", "a") //=> 1
str-index("abcde", "c") //=> 3
5.1.3 str-insert($string, $insert, $index)
看見 insert 這個詞我們就能猜到,這個函數是用于字符串的插入,str-insert($string, $insert, $index) 函數接收 3 個參數,第 1 個參數是一個字符串,第 2 個參數是要插入的字符串,第 3 個參數是插入的位置,返回結果是插入后的字符串:
str-insert("abcde", "j", 1) //=> "jabcde"
str-insert("abcde", "j", 4) //=> "abcjde"
str-insert("abcde", "j", 100) //=> "abcdej"
str-insert("abcde", "j", -20) //=> "jabcde"
從上面的例子我們可以看到,當第 3 個參數大于 $string 的長度,將會插入到,末尾;反之,如果小于 $string 長度的負值,則會插入到開始位置。
5.1.4 str-length($string)
這個函數用于獲取傳入的字符串的長度,只接收一個字符串參數,返回值是它的長度,返回值是 number 類型,我們舉例看下:
str-length("abcde") //=> 5
5.1.5 str-slice($string, $start-at, $end-at)
這個函數用于字符串的截取,str-slice($string, $start-at, $end-at) 函數接收 3 個參數,第 1 個參數是一個字符串,第 2 個參數是要截取的開始位置,第 3 個參數是要截取的結束位置,返回結果是截取到的字符串;要記住 Sass 的字符串截取函數返回的字符串是包含截取的開始和結束位置字符的,我們舉例看下:
str-slice("abcde", 1, 2) //=> "ab"
str-slice("abcde", 2, 4) //=> "bcd"
5.1.6 to-upper-case($string) 和 to-lower-case($string)
這兩個函數我們放在一起來講解,它們都接收 1 個字符串參數;to-upper-case($string) 函數 將傳入的字符串轉換為大寫并返回,to-lower-case($string) 函數將傳入的字符串轉換為小寫并返回:
to-upper-case("abcde") //=> "ABCDE" 轉為大寫
to-upper-case("Abc") //=> "ABC" 轉為大寫
to-lower-case("ABC") //=> "abc" 轉為小寫
to-lower-case("Abc") //=> "abc" 轉為小寫
5.1.7 unique-id()
unique-id() 函數會返回一個隨機的字符串,并且這個字符串在 Sass 編譯中是唯一的,這個我們用得不多,不過當你需要生成一個唯一的字符串標識的時候你可以使用它:
unique-id() //=> urgdjis
上面我們講解了字符串函數,字符串函數可以讓你方便地操作字符串,還為你提供了對字符串的增刪改查功能,下面我們來講解數字函數。
5.2 數字函數
Sass 提供了很多數字函數來提供計算和數值轉換等功能,在 Sass 中我們也稱之為 Math 函數,就像 javascript 中提供的 Math 函數一樣,為我們提供了很多數學上的計算,首先我們先舉例看一下簡單的僅有數學計算意義的數字函數:
math.$e //=> 2.7182818285 返回數學常數 e 的值
math.$pi //=> 3.1415926536 返回數學常數 π 的值
ceil(4.2) //=> 5 向上取整
floor(4.8) //=> 4 向下取整
round(4.3) //=> 4 四舍五入取近似值
round(4.7) //=> 5 四舍五入取近似值
abs(-10px) //=> 10px 取絕對值
math.cos(100deg) //=> -0.1736481777 返回余弦值,單位必須與deg兼容或無單位
math.sin(100deg) //=> 0.984807753 返回正弦值,單位必須與deg兼容或無單位
math.tan(100deg) //=> -5.6712818196 返回正切值,單位必須與deg兼容或無單位
math.acos(0.5) //=> 60deg 返回反余弦值,傳入的參數不可帶單位
math.asin(0.5) //=> 30deg 返回反正弦值,傳入的參數不可帶單位
math.atan(10) //=> 84.2894068625deg 返回反正切值,傳入的參數不可帶單位
random() //=> 返回一個 0~1 之間的隨機數
percentage(0.2) //=> 20% 將無單位的小數轉換為百分比數
5.2.1 math.log($number, $base)
這個函數用于計算對數,它會返回 $number 相對于 $base 的對數,這兩個參數是不可以帶有單位的。
math.log(10) //=> 2.302585093
math.log(10, 10) //=> 1
5.2.2 math.pow($base, $exponent)
math.pow($base, $exponent) 函數用于計算 $base 的 $exponent 次冪,是用于冪運算的。
math.pow(10, 2) //=> 100
5.2.3 math.sqrt($number)
math.sqrt($number) 函數返回傳入參數的平方根。
math.sqrt(100) //=> 10
5.2.4 comparable($number1, $number2)
comparable($number1, $number2) 用來判斷兩個數值的單位是否兼容,它的返回結果是布爾值,這個在你需要對單位進行要求的時候很有用,我們舉例看下:
comparable(10px, 10) //=> true
comparable(10px, 10px) //=> true
comparable(10px, 10em) //=> false
5.2.5 unitless($number)
unitless($number) 用于判斷傳入的數值是否沒有單位,返回結果是布爾值,如果沒帶單位返回 true,帶單位則返回 false。
unitless(100) //=> true
unitless(100px) //=> false
5.2.6 unit($number)
unit($number) 函數會返回傳入數值的單位,并且是將單位以字符串的形式返回的,我們來看下:
unit(8) //=> ""
unit(8px) //=> "px"
unit(8em) //=> "em"
5.2.7 max(KaTeX parse error: Expected 'EOF', got '和' at position 12: number...) 和? min(number…)
這兩個函數分別接收以逗號分隔的數值,并且分別返回其中最大的值和最小的值。
math.max(8, 4) //=> 8
math.min(8, 4) //=> 4
上面我們講了 Sass 中數字函數,這些函數是輔助你來對數字類型的值進行一些操作,很像 javascript 中提供的 Math 函數,你不需要死記硬背,這些函數需要用到的時候再查也可以。
5.3 列表函數
在前面的數據類型我們講過,在 Sass 中有一種數據類型是列表類型,那么列表函數就是用來操作列表的功能,下面我們一起來看下 Sass 提供了哪些列表函數。
5.3.1 append($list, $val, $separator)
append($list, $val, $separator) 函數用于向一個列表的末尾插入元素,它接收 3 個參數,第 1 個參數是一個列表(以空格或者逗號分隔),第 2 個參數是要插入的值(也可以是一個列表),第 3 個參數 $separator 表示返回的列表是否使用與 $list 相同的分隔符,這個默認是 auto ( 使用與$list相同的分隔符),這個函數的返回值也是一個列表。我們舉例看下:
append(10 11 12, 13) //=> 10 11 12 13
append((10,11,12), 13) //=> 10, 11, 12, 13
這里需要注意的是,如果第 1 個參數你是使用逗號分隔的列表,那么你要將這個列表使用括號括起來!
5.3.2 join($list1, $list2, $separator, $bracketed)
join($list1, $list2, $separator, $bracketed) 函數用于連接兩個列表,上面我們講到向列表默認插入元素,如果插入的元素是一個列表,那么請你使用 join 函數。
這個函數接收 4 個參數,第 1 個參數是一個列表,第 2 個參數是要插入的列表,第 3 個參數是返回列表的分隔符,默認是 auto (列表將使用與$list1相同的分隔符(如果有分隔符),否則使用與$list2相同的分隔符,或者使用空格。不允許使用其他值),第 4 個參數是布爾值,用來設置返回的列表是否包含方括號。我們舉例來看下:
join(5 6, 7 8) //=> 5 6 7 8
join((5,6), (7,8)) //=> 5, 6, 7, 8
join(5 6, 7 8, $bracketed: true) //=> [5 6 7 8]
這里需要注意的是,如果列表類型的參數是使用逗號分隔的列表,那么你要將這個列表使用括號括起來!
5.3.3 index($list, $value)
index($list, $value) 函數用于返回 $value 在列表 $list 中的索引,如果在 $list 中沒有 $value 則返回 null。
index(a b solid, b) //=> 2
index(a b solid, solid) //=> 3
5.3.4 length($list)
這個函數比較簡單,就是返回列表的長度。返回的值是 number 類型。
length(a b solid) //=> 3
length("") //=> 1
5.3.5 list-separator($list)
這個函數用來返回列表的分隔符,如果沒有分隔符就返回空格 space 。
list-separator(a b) //=> space
list-separator((a,b)) //=> comma
5.3.6 nth($list, $n)
nth($list, $n) 這個函數用于通過索引在列表中取元素,第 1 個參數是一個列表,第 2 個參數 $n 是索引位置,如果 $n 為負數,則從列表的末尾開始計數。如果索引 $n 處沒有元素,則引發錯誤。
nth(a b c d, 2) //=> b
上面講解了一些比較常見的列表函數,它很像 javascript 中提供的一些數組方法,在 Sass 中你可以對列表類型的數據使用各種各樣的列表函數來滿足你的需求。
5.4 Introspection函數
Introspection函數實際在樣式中寫的非常少,一般用于代碼的調試以及做一些判斷。這里我們只舉幾個例子來看下:
type-of(10px) //=> number 用于判斷數據的類型,返回數據的類型
type-of(10px 20px 30px) //=> list 用于判斷數據的類型,返回數據的類型
variable-exists("a") //=> false 用于判斷當前范圍中一個變量是否存在,這里是判斷變量 $a 是否存在
meta.module-variables($module) //=> 用于返回一個模塊中定義的所有變量
call($function, $args...) //=> 使用 $args 調用 $function,這個很像 javascript 中的 call
上面舉了幾個 Introspection函數的例子,這類函數一般很少直接用到樣式中,入門實戰你只需要了解有這類函數就可以,剛開始很少會直接應用。
5.5 條件函數
if($condition, $if-true, $if-false) 函數是 Sass 中的條件函數,它接收 3 個參數,第 1 個參數是一個判斷條件或者布爾值,第 2 個參數是當判斷條件為真時的返回值,第 3 個參數是當判斷條件為假時的返回值。我們舉例看下:
if(true, 18px, 16px) //=> 18px
if(true, 18px, 16px) //=> 16px
5.6 Map 函數
還記得我們在 Sass 數據類型章節講到的 Maps 類型嗎,Map 函數就是提供了很多操作 Maps 類型數據的功能。
5.6.1 map-get($map, $key)
map-get($map, $key) 函數是從 $map 中取出 key 為 $key 的值,第 1 個參數是 Maps 類型的數據,我們舉例看下:
$val_map: ("a": 1, "b": 2, "c": 3); // 定義 maps 類型的數據
map-get($val_map, "a") //=> 1
map-get($val_map, "b") //=> 2
這個函數就很像 javascript 中從 object 數據取值,它的功能也很單一,只是取值。
5.6.2 map-has-key($map, $key)
map-has-key($map, $key) 這個函數返回在 $map 中是否有 $key,返回的值是布爾類型。
$val_map: ("a": 1, "b": 2, "c": 3); // 定義 maps 類型的數據
map-has-key($val_map, "b")
map-has-key($val_map, "e") //=> false
5.6.3 map-keys($map)
map-keys($map) 函數返回傳入的 map 中所有的 key,并且會以逗號分隔為一個列表返回。
$val_map: ("a": 1, "b": 2, "c": 3); // 定義 maps 類型的數據
map-keys($val_map) //=> "a","b","c"
5.6.4 map-merge($map1, $map2)
map-merge($map1, $map2) 函數用于合并兩個 maps 類型的數據 $map1 和 $map2,并且會返回一個新的 map,如果 $map1 和 $map2 中有相同的 key ,那么 $map2 中的數據會覆蓋 $map1 中的這條數據,這個函數和 javascript 中合并兩個對象的方法很類似。我們舉例看下:
$val_map1: ("a": 1, "b": 2);
$val_map2: ("c": 3, "d": 4);
map-merge($val_map1, $val_map2)
// => 返回的數據
// (
// "a": 1,
// "b": 2,
// "c": 3,
// "d": 4
// )
5.6.5 map-remove($map, $keys…)
看到 remove 我們就知道這個是用來刪除的,map-remove($map, $keys…) 函數用來刪除 $map 中的一個或多個與 $keys 關聯的值,并且返回刪除后的 map。
$val_map: ("a": 1, "b": 2, "c": 3); // 定義 maps 類型的數據
map-remove($val_map, , "b") //=> ("c": 3)
5.6.6 map-values($map)
前面講到一個函數可以返回 map 中所有的 key ,map-values($map) 這個函數與其類似是用來返回 map 中所有的 value,同樣會以逗號分隔為一個列表返回。
$val_map: ("a": 1, "b": 2, "c": 3); // 定義 maps 類型的數據
map-values($val_map) //=> 1,2,3
到這里我們講了 Map 函數,你可以使用各種 Map 函數來對 Maps 數據類型進行操作和增刪改查。
5.7 顏色函數
Sass 中提供了非常非常多的顏色函數用來處理顏色值,它們很多需要你具有專業的調色及配色知識才能發揮出作用,所以本節我們不講的那么復雜,本節內容中我們只講幾種常見的、比較簡單的顏色函數,其他特別復雜的用于調色的函數在以后你可以再慢慢研究。
5.7.1 用于獲取通道色值的函數
Sass 提供了可以獲取一個色值中紅色通道、綠色通道和藍色通道色值的函數,它們分別是 red($color) 、green($color) 和 blue($color)。你可能還不太了解這三種通道是什么,不要緊,只要知道這三種函數和它的使用就可以。我們舉例看下:
blue(#BA55D3) //=> 211
red(#BA55D3) //=> 186
green(#BA55D3) //=> 85
5.7.2 saturate($color, $amount)
saturate($color, $amount) 函數用于調整 $color 的飽和度,第 1 個參數 $color 是一個顏色值,第 2 個參數是 0% ~ 100% 之間的百分數,其返回值也是一個顏色值。
saturate(#BA55D3, 20%) //=> #c740e8
5.7.3 scale-color(…)
這是一個非常強大的顏色函數,它接收很多個參數,可以調整一個色值的很多屬性,包括這個顏色的紅、綠、藍通道,以及亮度等等,我們只能舉例來直觀的看下:
scale-color(#BA55D3, $red: 15%) //=> #c455d3 調整紅色通道
scale-color(#BA55D3, $blue: 15%) //=> #ba55da 調整藍色通道
scale-color(#BA55D3, $lightness: -10%, $saturation: 10%) //=> #b338d2 調整亮度和飽和度
scale-color(#BA55D3, $alpha: -30%) //=> rgba(186, 85, 211, 0.7) 調整不透明度
通過上面的例子可以看到顏色函數提供了非常強大的用于調色的函數,駕馭它的前提是你要有非常豐富的調色知識以及一定的美術基礎。在實際的項目中我們非常少的用到顏色函數,因為一般都是由公司的 UI 設計師來進行調色,所以作為入門教程,你只需要了解 Sass 中的顏色函數就好。
6. 實戰經驗
上面用了非常長的篇幅講解了 Sass 提供的函數,基本都覆蓋了,那在實際的項目中我們是怎么應用的這些函數呢?哪些比較有用哪些不是很常用呢?一起來看下在我的項目中對 Sass 函數的應用:一般來說我們的項目中會有一個 function.scss 文件來單獨維護各種各樣的函數,我將我項目中 function.scss 文件中部分代碼粘貼出來:
// 截取字符串的后半部分
@function middleStr($str) {
$leng: str-length($str);
$start: $leng / 2;
@return str-slice($str, $start, $leng);
}
// 判斷class長度范圍
@function classLong($class, $max) {
$leng: str-length($class);
@if $leng > $max {
@return true;
} @else {
@return false;
}
}
// 大小寫轉換
@function upperOrLower($str, $type) {
@if type-of($str) == "string" {
@if $type == "upper" {
@return to-upper-case($str);
} @else {
@return to-lower-case($str)
}
}
}
上面的代碼中看出,一般我們使用 函數指令 @function 來定義我們自己的函數,這個自定義函數我們在后面的章節會單獨講解,在我的各種自定義函數中,我用到了本節內容所講的 Sass 提供的一些函數,這其中包括對字符串的操作等等,你可以從上面這段代碼中找出來,一般來說在項目中只有封裝一些通用的函數或指令的時候,會用到 Sass 提供的這些函數來輔助我們!
7. 小結
本節內容我們講了 Sass 提供的各種各樣的函數,基本覆蓋到了比較常用的、常見的函數,它們分別是:
- 字符串函數
- 數字函數
- 列表函數
- Introspection函數
- 條件函數
- Map 函數
- 顏色函數
我在這里列出 Sass 函數的一張長圖,這里基本涵蓋了常見的常用的函數,可以方便你復習和查閱 Sass 中的函數:
你需要多練習多使用這些函數,慢慢的就會記住它們了,我認為函數其實就是一系列的工具,多加使用,熟能生巧!