ฟังก์ชัน SASS

ฟังก์ชัน SASS

บทความนี้อธิบายเกี่ยวกับฟังก์ชันของ SASS

เราจะอธิบายฟังก์ชันของ SASS อย่างละเอียด ตั้งแต่พื้นฐานจนถึงหัวข้อขั้นสูง พร้อมตัวอย่างที่ใช้ได้จริงในงาน

YouTube Video

ฟังก์ชัน SASS

ฟังก์ชัน SASS เป็นเครื่องมือที่ทรงพลังในการรวมตรรกะที่ใช้ซ้ำได้ไว้ใน stylesheet ช่วยให้สามารถคำนวณ จัดรูปแบบ และแยกเงื่อนไข

โครงสร้างพื้นฐานและการใช้งานของฟังก์ชัน

ฟังก์ชัน 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-font มีค่าเริ่มต้นสำหรับ scale และ unit และสามารถละเว้นบางอาร์กิวเมนต์ได้ตอนเรียกใช้งาน ในตัวอย่างนี้ จะได้ค่าที่แสดงผลเช่น 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;

การส่งคืนและใช้งานลิสต์หรือแมพ

ฟังก์ชันสามารถส่งคืนลิสต์ (คั่นด้วยช่องว่างหรือคอมม่า) และแมพได้เช่นกัน สิ่งนี้มีประโยชน์สำหรับการส่งค่าที่ซับซ้อน

 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.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 และคูณหรือลบตามจำนวนสเต็ปบวกหรือลบ 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// }
  • หากส่งค่าที่ไม่ถูกต้อง จะมี error แสดงออกมาในขั้นตอน build ทำให้หาสาเหตุได้ง่าย การตรวจสอบในฟังก์ชันช่วยให้เจอบั๊กได้ตั้งแต่เนิ่นๆ

การสร้างฟังก์ชันเฉพาะสำหรับสี

ใน 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 จะถูกประมวลผลในขั้นตอนคอมไพล์ การใช้ลูปจำนวนมาก recursion ที่ซับซ้อน หรือการจัดการแมพขนาดใหญ่ จะทำให้เวลาคอมไพล์เพิ่มขึ้น ควรเขียนฟังก์ชันให้เล็กและเรียบง่าย และถ้าจำเป็น ควรย้ายการประมวลผลที่ซับซ้อนออกไปไว้ใน build tool หรือ preprocessor แทน

ชุดฟังก์ชันยูทิลิตี้ที่ใช้บ่อย

นี่คือฟังก์ชันยูทิลิตี้ที่มักใช้งานจริง โค้ดชุดนี้ออกแบบมาให้สามารถนำไปใช้กับโปรเจกต์จริงได้ทันที

 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 ทั้งสองฟังก์ชันนี้ช่วยให้งานที่พบได้บ่อยในการออกแบบ responsive ทำได้ง่ายขึ้น

การเลือกใช้ระหว่าง @function และมิกซ์อิน (@mixin)

ฟังก์ชันเน้นในการส่งคืนค่า ในขณะที่มิกซ์อินจะสร้างโค้ด CSS ทั้งบล็อก ถ้าต้องการผลลัพธ์เป็นค่าเดียว ให้ใช้ฟังก์ชัน แต่ถ้าเป็นกลุ่มของ property ให้ใช้มิกซ์อิน

 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}
  • ฟังก์ชันจะคืนค่าตัวเลขหรือสี สำหรับใช้งานกับ property อื่นๆ ส่วนมิกซ์อินจะแทรกกลุ่ม property ลงไปโดยตรง การแยกบทบาทอย่างชัดเจนในการออกแบบจะช่วยให้ดูแลโค้ดได้ง่ายขึ้น

การจัดการสตริงและข้อควรระวังเกี่ยวกับรูปแบบผลลัพธ์

โปรดระวังเมื่อใช้งานตัวเลขที่มีหน่วยและสตริงใน SASS การนำสตริงมาต่อกับตัวเลขที่มีหน่วย อาจทำให้ได้ผลลัพธ์ไม่ตรงที่ต้องการ ใช้ unquote() หรือ string interpolation (#{}) ตามความเหมาะสม

 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}
  • เมื่อคืนเปอร์เซ็นต์ในรูปแบบสตริง ให้จัดการจำนวนทศนิยมโดยใช้ interpolation หรือ round เพื่อให้ผลลัพธ์ชัดเจน เพื่อป้องกันปัญหา ควรจัดการชนิดข้อมูลให้ชัดเจน ทุกครั้งที่ต่อผลลัพธ์การคำนวณกับสตริง

แนวปฏิบัติที่ดีที่สุดสำหรับการทดสอบและเอกสาร

หลังจากเขียนฟังก์ชันแล้ว ควรสร้างไฟล์ 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 ฟังก์ชันยูทิลิตี้สำหรับเรื่องสี การเว้นระยะ และการแปลงหน่วย เหมาะจะนำไปรวมไว้ในไลบรารีกลาง เพื่อไม่ให้การคอมไพล์หนัก ควรแยกกระบวนการที่ซับซ้อนออกไปทำในขั้นตอน build อื่นๆ เมื่อจำเป็น

คุณสามารถติดตามบทความข้างต้นโดยใช้ Visual Studio Code บนช่อง YouTube ของเรา กรุณาตรวจสอบช่อง YouTube ด้วย

YouTube Video