มิกซ์อินใน SASS

มิกซ์อินใน SASS

บทความนี้อธิบายเกี่ยวกับมิกซ์อินใน SASS

เราจะอธิบายมิกซ์อินใน SASS ด้วยตัวอย่างเชิงปฏิบัติ

YouTube Video

มิกซ์อินใน SASS

ภาพรวม – มิกซ์อินคืออะไร?

มิกซินเป็นกลไกที่ช่วยให้คุณสามารถกำหนดชุดคุณสมบัติของสไตล์ที่ใช้บ่อยเป็นฟังก์ชันที่นำกลับมาใช้ใหม่ได้ ซึ่งคุณสามารถเรียกใช้งานได้ทุกที่ที่ต้องการ มิกซ์อินมีประโยชน์มากในการทำให้คลาส CSS ของคุณและพร็อพเพอร์ตี้ต่างๆ รักษาหลัก DRY (Don't Repeat Yourself)

ตัวอย่าง: มิกซ์อินอย่างง่ายที่สุด

ตัวอย่างด้านล่างเป็นมิกซ์อินง่ายๆ ที่นำ border-radius และ box-shadow มาใช้ร่วมกัน โดยการเรียกใช้มิกซ์อินนี้ คุณสามารถนำรูปลักษณ์เดียวกันไปใช้กับหลายองค์ประกอบได้

 1// Simple mixin that applies border-radius and box-shadow
 2@mixin card-style {
 3  border-radius: 8px;
 4  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.12);
 5  background: #fff;
 6}
 7
 8.card {
 9  @include card-style;
10  padding: 1rem;
11}
  • ด้วยมิกซ์อินนี้ คุณไม่จำเป็นต้องเขียนสไตล์ซ้ำๆ อีกต่อไป
  • การเรียกใช้เพียงแค่บรรทัดเดียว คือ @include card-style;

มิกซ์อินที่มีอาร์กิวเมนต์ (พารามิเตอร์)

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

 1// Mixin with parameters: accepts a color and optional radius
 2@mixin colored-box($bg-color, $radius: 4px) {
 3  background-color: $bg-color;
 4  border-radius: $radius;
 5  padding: 0.75rem;
 6}
 7
 8.box-primary {
 9  @include colored-box(#007acc);
10}
11
12.box-custom {
13  @include colored-box(#ffcc00, 12px);
14}
  • โดยการกำหนดค่าพื้นฐาน คุณสามารถควบคุมพฤติกรรมเมื่อไม่ได้ระบุอาร์กิวเมนต์ได้
  • ในตัวอย่างนี้จะใช้ radius ค่าเริ่มต้น และเปลี่ยนเฉพาะสีพื้นหลัง

ตัวอย่างการใช้อาร์กิวเมนต์แบบหลายค่า (variadic arguments, ...)

เมื่อคุณต้องการรับค่าหลายค่า สามารถใช้อาร์กิวเมนต์แบบหลายค่า ($args...) ได้ สิ่งนี้มีประโยชน์ในการสร้างคลาสยูทิลิตี้ หรือส่งลิสต์ fallback ต่างๆ

เหมาะสำหรับการส่งค่า family ของฟอนต์หลายชุด หรือค่าของ shadow หลายค่า

1// Mixin that accepts variable arguments and forwards them to box-shadow
2@mixin multi-shadow($shadows...) {
3  box-shadow: $shadows;
4}
5
6.panel {
7  @include multi-shadow(0 2px 4px rgba(0,0,0,0.08), 0 8px 16px rgba(0,0,0,0.06));
8}
  • ฝั่งที่เรียกใช้สามารถส่งค่า shadow หลายค่าโดยคั่นด้วยลูกน้ำ
  • ด้วยวิธีนี้ คุณสามารถใช้มิกซ์อินตัวเดียวกันสำหรับ shadow แบบง่ายและแบบซับซ้อนได้

มิกซ์อินที่ใช้ @content — รับบล็อกของสไตล์

ด้วย @content มิกซ์อินสามารถรับบล็อกของสไตล์จากผู้เรียกได้ สิ่งนี้ทำให้มิกซ์อินสามารถให้โครงสร้างครอบหรือ wrapper ได้ ส่วนผู้เรียกเป็นผู้กำหนดรายละเอียดภายใน

 1// Mixin that sets up a responsive container and yields to caller via @content
 2@mixin responsive-container($max-width: 1200px) {
 3  margin-left: auto;
 4  margin-right: auto;
 5  padding-left: 1rem;
 6  padding-right: 1rem;
 7  max-width: $max-width;
 8
 9  @content; // place where caller's styles are inserted
10}
11
12.header {
13  @include responsive-container(1000px) {
14    display: flex;
15    align-items: center;
16    justify-content: space-between;
17  }
18}
  • ฝั่งที่เรียกคุณสามารถใส่บล็อกเข้าไปใน @include เพื่อแทรกสไตล์ภายใน
  • รูปแบบนี้มีประโยชน์สำหรับโครงร่างจัดวางเช่น grid, card หรือฟอร์ม

มิกซ์อินขั้นสูงโดยใช้เงื่อนไขและลูป

โครงสร้างควบคุมอย่าง @if และ @for สามารถใช้ภายในมิกซ์อินได้ สิ่งเหล่านี้ใช้ในการสร้างยูทิลิตี้อัตโนมัติหรือจัดกลุ่ม settings แบบ responsive ได้

ตัวอย่างด้านล่างนี้คือการสร้างคลาสยูทิลิตี้สำหรับความกว้างแบบอัตโนมัติ

 1@use 'sass:math';
 2
 3// Mixin that generates width utility classes from a list of fractions
 4@mixin generate-widths($fractions) {
 5  @each $name, $fraction in $fractions {
 6    .w-#{$name} {
 7      width: math.percentage($fraction);
 8    }
 9  }
10}
11
12$widths: (
13  '1-4': 0.25,
14  '1-3': 0.3333,
15  '1-2': 0.5,
16  '3-4': 0.75
17);
18
19@include generate-widths($widths);
  • เพียงแค่ส่งแผนที่ของเศษส่วนที่คุณต้องการสร้างในฝั่งที่เรียกใช้ คุณก็สามารถสร้างคลาสยูทิลิตี้ที่เกี่ยวข้องทั้งหมดได้โดยอัตโนมัติในครั้งเดียว
  • การใช้วิธีนี้มีข้อดีคือช่วยลดการกำหนดสไตล์ด้วยตนเองในขณะที่ยังคงความสม่ำเสมอไว้ในงานออกแบบของคุณ

เปรียบเทียบมิกซ์อินและ Placeholder (%placeholder)

ในขณะที่มิกซินจะแทรกชุดของคุณสมบัติโดยตรง แต่เพลซโฮลเดอร์จะใช้ร่วมกับ @extend เมื่อมีการรับช่วงต่อสไตล์ มิกซินอาจสร้าง CSS ซ้ำซ้อนในบางกรณี แต่ @extend สามารถทำให้ CSS กระชับมากขึ้นในบางสถานการณ์

โดยการเข้าใจวัตถุประสงค์และความแตกต่างของ CSS ที่ถูกสร้างขึ้นจากแต่ละวิธี คุณจะสามารถเลือกแนวทางที่เหมาะสมที่สุดได้

 1// Placeholder example (for comparison)
 2%btn-base {
 3  display: inline-block;
 4  padding: 0.5rem 1rem;
 5  border-radius: 4px;
 6}
 7
 8.btn-primary {
 9  @extend %btn-base;
10  background: #007acc;
11  color: #fff;
12}
13
14.btn-secondary {
15  @extend %btn-base;
16  background: #e0e0e0;
17}
  • เมื่อคุณ @extend เพลซโฮลเดอร์ ตัวเลือกหลายตัวสามารถถูกรวมไว้ในกฎเดียวกัน ส่งผลให้ CSS กระชับมากขึ้น
  • ในทางกลับกัน เนื่องจากมิกซินจะแทรกคุณสมบัติโดยตรงในตำแหน่งที่ต้องการ จึงให้ความยืดหยุ่นและช่วยหลีกเลี่ยงการรวมตัวเลือกโดยไม่ตั้งใจ

รูปแบบที่ใช้กันบ่อยในทางปฏิบัติ (responsive, vendor prefix ฯลฯ)

ในทางปฏิบัติ การนำกระบวนการทั่วไปเช่น vendor prefix และฟีเจอร์ responsive ไว้ในมิกซ์อินจะสะดวกมาก ตัวอย่างข้างล่างนี้เป็นการรวมพร็อพเพอร์ตี้ transform กับ prefix ต่างๆ คุณสามารถรวมโค้ดเพื่อความเข้ากันได้ของเบราว์เซอร์ ช่วยให้ง่ายต่อการดูแลในภายหลัง

 1// Mixin for transform with vendor prefixes
 2@mixin transform($value) {
 3  -webkit-transform: $value;
 4  -ms-transform: $value;
 5  transform: $value;
 6}
 7
 8.icon-rotate {
 9  @include transform(rotate(45deg));
10}
  • การใช้งานนั้นง่ายและคุณสามารถใช้ได้ทุกที่ เช่น @include transform(rotate(10deg));
  • แม้ในอนาคตจะไม่จำเป็นต้องใช้คำนำหน้า การดูแลรักษาก็จะง่ายขึ้น เพราะเมื่ออัปเดตมิกซินจะทำให้โค้ดทั้งหมดเปลี่ยนแปลงตามไปด้วย

ตัวอย่างการใช้งานจริง: การผสมผสาน card และปุ่ม

ด้านล่างนี้คือตัวอย่างที่รูปแบบปุ่มซึ่งใช้ภายในการ์ดถูกรวมเป็นหนึ่งเดียวด้วยมิกซ์อิน ทำให้สามารถเปลี่ยนแปลงได้ตามสีธีม

สิ่งนี้จะจัดการรูปแบบ 'การ์ด + ปุ่ม' ที่ใช้บ่อยโดยใช้มิกซ์อิน

 1// Simple mixin that applies border-radius and box-shadow
 2@mixin card-style {
 3  border-radius: 8px;
 4  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.12);
 5  background: #fff;
 6}
 7
 8// Mixin for transform with vendor prefixes
 9@mixin transform($value) {
10  -webkit-transform: $value;
11  -ms-transform: $value;
12  transform: $value;
13}
14
15// Button mixin with theme and size parameters
16@mixin btn($bg, $color: #fff, $padding: 0.5rem 1rem) {
17  display: inline-block;
18  padding: $padding;
19  background: $bg;
20  color: $color;
21  border-radius: 6px;
22  text-decoration: none;
23  cursor: pointer;
24  @include transform(translateY(0)); // reuse earlier transform mixin
25}
26
27// Card mixin that accepts inner button styling via @content
28@mixin card($gap: 1rem) {
29  @include card-style; // reuse earlier card-style mixin
30  padding: $gap;
31  @content;
32}
33
34.card-feature {
35  @include card {
36    .title { font-size: 1.125rem; margin-bottom: 0.5rem; }
37    .cta {
38      @include btn(#007acc);
39    }
40  }
41}
42
43.card-warning {
44  @include card {
45    .title { font-weight: bold; }
46    .cta {
47      @include btn(#ff6600);
48    }
49  }
50}
  • โดยใช้มิกซ์อินเหล่านี้ คุณสามารถเขียนคอมโพเนนต์ให้กระชับได้

ใส่ใจเรื่องประสิทธิภาพและ CSS ที่ถูกสร้างขึ้น

เนื่องจากมิกซ์อินจะเพิ่มพร็อพเพอร์ตี้ทุกครั้งที่ถูกเรียก หากใช้ @include ซ้ำๆ สำหรับกฎเดียวกัน อาจทำให้ไฟล์ CSS มีขนาดใหญ่ขึ้น คุณสามารถปรับปรุงโดยผสมกับ placeholder และการออกแบบคอมโพเนนต์เมื่อจำเป็น

นอกจากนี้ มาตรการดังต่อไปนี้ก็มีประสิทธิผลเช่นกัน

  • สไตล์ที่ใช้งานบ่อยควรถูกสร้างเป็นคลาสเพื่อให้นำกลับมาใช้ซ้ำได้
  • รูปแบบที่พบบ่อยควรถูกรวมกลุ่มด้วยการใช้ @content
  • การสร้างยูทิลิตี้ที่ซับซ้อนควรทำเฉพาะในช่วงเวลาการสร้าง(build time)เท่านั้น

เคล็ดลับเพื่อการดีบั๊กที่ง่ายขึ้น

เมื่อใช้งานมิกซ์อิน ควรคิดค้นวิธีเพื่อปรับปรุงการดีบักและการดูแลรักษาด้วย โดยการใช้ชื่อตัวแปรที่ชัดเจนและใส่คอมเมนต์ในมิกซิน จะช่วยให้เข้าใจได้ง่ายขึ้นเมื่อทบทวนโค้ดในภายหลัง นอกจากนี้ หากฟังก์ชันนั้นซับซ้อน การแยกมิกซ์อินออกเป็นหน่วยย่อยๆ จะทำให้ง่ายต่อการทดสอบและเพิ่มความง่ายในการดูแลรักษา

นอกจากนี้ การเปิดใช้ซอร์สแม็ปจะช่วยให้คุณสามารถติดตามได้ง่ายว่ามิกซ์อินใดเป็นผู้สร้าง CSS ใด ลดขั้นตอนในการแก้ไขปัญหา

ด้านล่างนี้คือตัวอย่างของมิกซ์อินที่เข้าใจง่าย พร้อมคอมเมนต์เอกสารประกอบ

1// Example: readable mixin with clear param names and comments
2/// Adds a subtle focus ring for accessibility
3/// $color - ring color
4/// $size - thickness of the ring
5@mixin focus-ring($color: #007acc, $size: 2px) {
6  outline: none;
7  box-shadow: 0 0 0 $size rgba(blue($color), 0.15);
8}
  • การมีคอมเมนต์เอกสารที่จัดระเบียบไว้แบบนี้ จะช่วยให้สามารถแบ่งปันและเข้าใจภายในทีมได้ง่ายขึ้น
  • เนื่องจากคอมเมนต์เอกสารของ SASS สามารถถูกดึงออกมาได้โดยอัตโนมัติด้วยเครื่องมือที่รองรับ จึงมีประโยชน์ต่อการสร้างเอกสาร เช่น ไกด์ไลน์สไตล์

สรุป

เพราะมิกซ์อินช่วยรวมสไตล์ที่ใช้บ่อยไว้ใช้ซ้ำ ช่วยลดโค้ดซ้ำและเพิ่มการดูแลรักษา นอกจากนี้ หาก selector หลายตัวใช้กฎเดียวกัน ลองใช้ทั้งมิกซ์อินและ @extend (placeholder) ด้วย นอกจากนี้ @content ช่วยให้แยกส่วน layout และเนื้อหาได้อย่างยืดหยุ่น แต่ถ้าใช้ @include มากเกินไป อาจทำให้ CSS ที่ถูกสร้างมีขนาดใหญ่ขึ้น โปรดใช้ด้วยความระมัดระวัง การใช้ arguments, ค่า default และ variadic argument อย่างเหมาะสม เป็นหัวใจสำคัญในการออกแบบมิกซ์อินให้สามารถนำไปใช้ทั่วไปและขยายต่อได้ง่าย

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

YouTube Video