มิกซ์อินใน 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 ด้วย