การดูแลรักษาสไตล์ชีตขนาดใหญ่มักทำให้เกิดตรรกะที่ซ้ำซ้อน โดยเฉพาะเมื่อต้องจัดการกับโทเค็นระบบการออกแบบ เช่น การไล่ระดับสีหรือรูปแบบเลย์เอาต์ที่ปรับเปลี่ยนตามอุปกรณ์
กฎ @function at-rule ของ CSS ช่วยให้คุณรวมตรรกะนี้ไว้ในฟังก์ชันที่ใช้ซ้ำได้และมีพารามิเตอร์ ซึ่งทำให้ CSS ของคุณดูแลรักษาได้ง่ายขึ้น สอดคล้องกัน และเป็นไปตามหลัก DRY (Don't Repeat Yourself)
ไวยากรณ์ @function
ฟังก์ชันที่กำหนดเองจะกำหนดโดยใช้กฎ @function ตามด้วยชื่อที่มีขีดกลางและรายการพารามิเตอร์ ฟังก์ชันจะแสดงผลค่าโดยใช้พร็อพเพอร์ตี้ result
@function --my-function(--input1 <length>, --input2: default-value) returns <length> {
/* Logic goes here */
result: var(--input1);
}
หัวข้อสำคัญ
- พารามิเตอร์: ต้องขึ้นต้นด้วยขีดกลาง 2 ขีด (
--) - ค่าเริ่มต้น: คุณระบุค่าเริ่มต้นได้โดยใช้โคลอน (
:) - ผลลัพธ์: พร็อพเพอร์ตี้
resultจะกำหนดค่าที่ฟังก์ชันแสดงผลresultสุดท้ายที่ประกาศในเนื้อหาฟังก์ชันจะชนะ - การกำหนดขอบเขต: พารามิเตอร์และตัวแปรที่กำหนดไว้ภายในฟังก์ชันจะมีขอบเขตเฉพาะที่
- ประเภท: คุณสามารถกำหนดให้พารามิเตอร์และค่าที่แสดงผลตรงกับประเภท CSS ด้วยสัญกรณ์วงเล็บ (เช่น
<color>) และอนุญาตให้ใช้หลายประเภทด้วยฟังก์ชันtype(เช่นtype(<number> | <percentage>))
ตัวอย่างที่นำไปใช้ได้จริง
1. โทเค็นระบบการออกแบบ (การไล่ระดับสี)
ตรวจสอบว่าการไล่ระดับสีสอดคล้องกันทั่วทั้งแอปโดยการรวมตรรกะการไล่ระดับสี --angle จะระบุค่าเริ่มต้นเพื่อให้มีความสอดคล้องกันซึ่งสามารถลบล้างได้
@function --fancy-gradient(--start-color <color>, --end-color <color>, --angle: 98deg) returns <image>{
result: linear-gradient(in oklab var(--angle), var(--start-color), var(--end-color) );
}
.card {
background: --fancy-gradient(#ed73d7, #5d87e9);
}
2. ตรรกะเลย์เอาต์แบบมีเงื่อนไข
คุณสามารถใช้ @media หรือคำค้นหาอื่นๆ ภายในฟังก์ชันโดยตรงเพื่อแสดงผลค่าต่างๆ ตามสภาพแวดล้อม เมื่อใช้ตรรกะแบบมีเงื่อนไขในฟังก์ชัน โปรดทราบว่า @function จะไม่ "แสดงผล" ที่ค่าแรกของ result แต่จะทำตาม CSS Cascade และแสดงผลเป็นค่าสุดท้ายที่ตรงกันตามขนาดหน้าจอ ขนาดคอนเทนเนอร์ หรือการค้นหาอื่นๆ
@function --grid-template(--count <number>){
/* MANDATORY: Put default value first. */
result: 1fr; /* Default: stack */
@media (min-width: 800px) {
result: repeat(var(--count), 1fr); /* Grid on larger screens */
}
}
main {
display: grid;
grid-template-columns: --grid-template(2);
}
แนวทางปฏิบัติแนะนำ
- ใช้ชื่อที่มีขีดกลาง: นำหน้าชื่อฟังก์ชันและพารามิเตอร์ด้วย
--เสมอ - ระบุค่าเริ่มต้น: ทำให้ฟังก์ชันมีประสิทธิภาพมากขึ้นด้วยการระบุค่าเริ่มต้นที่เหมาะสม
- เรียบง่ายเข้าไว้: ใช้ฟังก์ชันสำหรับตรรกะที่มีการทำซ้ำหรือซับซ้อนจริงๆ อย่าออกแบบคู่พร็อพเพอร์ตี้-ค่าที่เรียบง่ายให้ซับซ้อนเกินไป
- ใช้ประเภท: ตรวจสอบว่าพารามิเตอร์และค่าที่แสดงผลเป็นประเภทที่คาดไว้
- พิจารณาทางเลือกที่คอมไพล์ไว้ล่วงหน้า: สำหรับฟังก์ชันที่ไม่ได้ขึ้นอยู่กับอินพุตของผู้ใช้, Media Query หรือรูปแบบอื่นๆ ฝั่งไคลเอ็นต์ ให้พิจารณาใช้คอมไพล์เลอร์ CSS ล่วงหน้าเพื่อหลีกเลี่ยงการทำงานที่ไม่จำเป็นในฝั่งไคลเอ็นต์
กลยุทธ์สำรอง
ในเบราว์เซอร์ที่ไม่รองรับฟังก์ชัน CSS ค่าที่ตั้งไว้โดยใช้ฟังก์ชัน CSS จะใช้ไม่ได้ หากต้องการรองรับเบราว์เซอร์อื่นๆ ให้ระบุค่าสำรองสำหรับพร็อพเพอร์ตี้ก่อน ระบบจะลบล้างค่านี้ในเบราว์เซอร์ที่รองรับฟังก์ชัน CSS
.card {
/* Provide fallback, in this case a solid color. */
background: #5d87e9;
background: --fancy-gradient(#ed73d7, #5d87e9);
}
main {
/* Provide fallback, in this case a simple stacked default. */
grid-template-columns: 1fr;
grid-template-columns: --grid-template(2);
}
หากจำเป็นต้องลดการทำซ้ำสไตล์ขณะที่รองรับเบราว์เซอร์อื่นๆ ให้พิจารณาใช้คอมไพเลอร์ CSS ล่วงหน้าที่มีฟังก์ชัน เช่น Sass