ลดการทำซ้ำสไตล์ด้วยฟังก์ชัน CSS

ฟีเจอร์เว็บ: @function

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

กฎ @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