SASS 函數

本文章將說明 SASS 函數。

我們將從基礎到進階,徹底解說 SASS 函數,並包含實務工作中實用的範例。

YouTube Video

SASS 函數

SASS 函數是將可重複使用邏輯封裝於樣式表中的強大工具,可以實現計算、格式化及條件分支。

函數的基本結構與用法

SASS 函數使用 @function 定義,並以 @return 回傳值。函數的調用方式與內建函數相同。

1// Example: Define a simple function that doubles a value
2@function double($n) {
3  @return $n * 2;
4}
5
6// Use the function
7.example {
8  width: double(10px);  // -> 20px
9}
  • 此代碼定義了一個將數字加倍並應用於寬度的函數。結果會生成 .example { width: 20px; }

引數、預設值與型別處理

函數可以接收多個引數,並設定預設值。SASS 並未強制靜態型別,但注意引數格式可提升函數的健壯性。

1// Example: Function with default parameters
2@function responsive-font($base-size, $scale: 1.2, $unit: px) {
3  @return $base-size * $scale + $unit;
4}
5
6.title {
7  font-size: responsive-font(16, 1.25);  // -> 20px
8}
  • responsive-fontscaleunit 提供了預設值,因此呼叫時可省略部分引數。在此範例中,將會輸出像是 font-size: 20px; 的數值。

使用可變引數(...

如果希望傳遞多個值,可以使用可變引數。這對於處理清單或多個顏色非常有用。

 1// Example: Sum any number of numbers passed in
 2@function sum-all($numbers...) {
 3  $total: 0;
 4  @each $n in $numbers {
 5    $total: $total + $n;
 6  }
 7  @return $total;
 8}
 9
10.box {
11  padding: sum-all(4px, 6px, 10px);  // -> 20px
12}
  • $numbers... 這樣的可變引數會被當作清單,可以用 @each 逐一處理。在此範例中,將會輸出 padding: 20px;

回傳與操作清單或映射(map)

函數也可以回傳清單(用空格或逗號分隔)及映射(map)。這對回傳複雜的值非常有幫助。

 1@use "sass:map";
 2
 3// Example: Return a map of spacing scale
 4@function spacing-scale($base) {
 5  @return (
 6    'small': $base * 0.5,
 7    'medium': $base,
 8    'large': $base * 2
 9  );
10}
11
12$scale: spacing-scale(8px);
13
14.card {
15  margin-bottom: map.get($scale, 'medium');
16}
  • 這個函數會返回一個 map,然後可以透過 map.get 取得數值。這讓你能維持一致的間距系統。

含條件與迴圈的函數

@if@else if@else@for@each@while 都能用於函數內。可利用條件與迴圈建立計算邏輯。

 1// Example: Generate modular scale value using loop
 2@function modular-scale($step, $base: 1rem, $ratio: 1.25) {
 3  $result: $base;
 4  @if $step == 0 {
 5    @return $result;
 6  }
 7  @if $step > 0 {
 8    @for $i from 1 through $step {
 9      $result: $result * $ratio;
10    }
11  } @else {
12    @for $i from 1 through abs($step) {
13      $result: $result / $ratio;
14    }
15  }
16  @return $result;
17}
18
19.h1 {
20  font-size: modular-scale(3, 1rem, 1.333);
21}
  • 此函數會計算一個模組化比例,根據正負步長進行乘除運算。modular-scale(3, 1rem, 1.333) 會回傳比基準值高三級的字體大小。

錯誤處理與警告(@error@warn

遇到無效參數或非預期操作時,可用 @error 終止,並用 @warn 發出警告。目的在於及早提醒使用者有問題出現。

 1@use "sass:math";
 2@use "sass:meta";
 3
 4// Example: Validate input and throw an error for invalid units
 5@function ensure-length($value) {
 6  @if meta.type-of($value) != 'number' or math.is-unitless($value) {
 7    @error "Expected a length with units, got #{$value}.";
 8  }
 9  @return $value;
10}
11
12// Valid input (should pass)
13.test-valid {
14  width: ensure-length(10px); // expect: 10px
15}
16
17// Invalid input (should throw error during compilation)
18// Uncomment the following to test error handling:
19//
20// .test-invalid {
21//   // expect error: "Expected a length with units, got 10."
22//   width: ensure-length(10);
23// }
  • 如果傳遞無效值,建置時會輸出錯誤,更容易找出原因。在函數內做檢查,有助於及早發現錯誤。

製作特定顏色用函數

在 SASS 中,你可以結合多種顏色操作函數來創建自己的配色方案。這對於在整個專案中保持一致的色彩方案非常有用。

 1@use "sass:color";
 2@use "sass:list";
 3
 4// Example: Generate a color palette (tints and shades) from a base color
 5@function palette($color, $steps: 5, $strength: 10%) {
 6  $colors: ();
 7  @for $i from 0 through $steps {
 8    $amount: $i * $strength;
 9    $shade: if($i == 0, $color, color.mix(black, $color, $amount));
10    $tint: color.mix(white, $color, $amount);
11    $colors: list.append($colors, $shade);
12    $colors: list.append($colors, $tint);
13  }
14  @return $colors;
15}
16
17$palette: palette(#3498db, 3, 15%);
18
19.btn {
20  background-color: list.nth($palette, 1);
21}
  • 在此範例中,color.mix 用於與黑色混合製造陰影,與白色混合製造亮色。數值會以列表的形式返回,並可使用 list.nth 來存取。

效能與編譯時間注意事項

SASS 函數在編譯時執行。大量迴圈、深層遞迴或大規模映射操作會延長編譯時間。請保持函數小巧單純,若有複雜邏輯,建議搬到 SASS 以外的建構工具或前處理器來處理。

實用輔助函數集

這裡有一些常用的輔助函數。這些程式碼可直接於實際專案中使用。

 1@use "sass:math";
 2
 3// Example: Clamp a value between min and max
 4@function clamp-value($value, $min, $max) {
 5  @if $value < $min {
 6    @return $min;
 7  } @else if $value > $max {
 8    @return $max;
 9  }
10  @return $value;
11}
12
13// Example: Convert px to rem (with optional root size)
14@function px-to-rem($px, $root: 16px) {
15  @if math.unit($px) != "px" {
16    @error "px-to-rem requires a px value.";
17  }
18  @return ($px / $root) * 1rem;
19}
  • clamp-value 用於設置數值的上限與下限,而 px-to-rem 則將像素值轉換為 rem。這兩者都能簡化響應式設計中常見的處理流程。

選擇 @function 或 Mixins(@mixin

函數專注於回傳值,mixin 則輸出 CSS 區塊。若計算結果為單一屬性值時請用函數,若為整組樣式則使用 mixin。

 1// Example: Function returns a value
 2@function border-radius-value($size) {
 3  @return $size * 1px;
 4}
 5
 6// Example: Mixin outputs properties
 7@mixin rounded($size) {
 8  border-radius: border-radius-value($size);
 9  -webkit-border-radius: border-radius-value($size);
10}
11.card {
12  @include rounded(8);
13}
  • 函數回傳數字或顏色等值,可給其他屬性用;mixin 則直接插入一組屬性。嚴格區分設計可提升可維護性。

字串處理與輸出格式注意事項

處理 SASS 中帶單位的數字與字串時請特別注意。將帶單位的數字與字串串接時,可能會產生非預期結果。請根據需求使用 unquote() 或字串插值(#{})。

 1@use "sass:math";
 2
 3// Example: Safely create a CSS value string
 4@function px-percentage($px, $total) {
 5  $percent: math.div($px, $total) * 100;
 6  @return "#{$percent}%";
 7}
 8
 9// Safer with interpolation and math module
10@function px-percentage-safe($px, $total) {
11  $percent: math.div($px, $total) * 100;
12  // Round to 2 decimal places safely
13  $rounded: math.div(math.round($percent * 100), 100);
14  @return "#{$rounded}%";
15}
  • 回傳百分比字串時,請用插值或 round 控制精度,以提升可讀性。為避免 bug,串接運算結果與字串時,請確實處理資料型態。

測試與文件的最佳實踐

撰寫函數後,另建小型 SCSS 檔案附上範例作為測試,有助於維護。可為每個函數記錄輸入類型/單位、回傳類型、錯誤時的行為及用法範例。

 1@use "sass:math";
 2
 3// Example: Inline "tests" (partial usage examples)
 4// These can be compiled separately during development
 5
 6@function double($n) {
 7  @return $n * 2;
 8}
 9
10@function px-to-rem($px, $root: 16px) {
11  @if math.unit($px) != "px" {
12    @error "px-to-rem requires a px value.";
13  }
14  @return math.div($px, $root) * 1rem;
15}
16
17// Test double()
18.test-double {
19  width: double(12px); // expect 24px
20}
21
22// Test px-to-rem()
23.test-rem {
24  font-size: px-to-rem(18px, 18px); // expect 1rem
25}
26
27// --- Inline debug tests ---
28@debug "double(12px) => #{double(12px)} (expect 24px)";
29@debug "px-to-rem(18px, 18px) => #{px-to-rem(18px, 18px)} (expect 1rem)";
  • 在文件中註明『預期輸出』的小範例,有助於日後重構時發現倒退錯誤。於 CI 環境自動編譯並目視檢查輸出效果良好。

總結

SASS 函數能大幅提高樣式的重用性與一致性。請設計為小而簡單,並用 @error@warn 保障安全性。顏色、間距、單位轉換等輔助函數建議收斂於共用函式庫。為避免編譯負擔,必要時請將複雜處理移出 SASS,由其他建構步驟處理。

您可以在我們的 YouTube 頻道上使用 Visual Studio Code 來跟隨上述文章一起學習。 請也查看我們的 YouTube 頻道。

YouTube Video