เลเยอร์ตามลำดับชั้น (@layer
กฎ CSS) จะพร้อมใช้งานใน Chromium 99, Firefox 97 และ Safari 15.4 เบต้า ซึ่งช่วยให้ควบคุมไฟล์ CSS ได้อย่างชัดเจนมากขึ้นเพื่อป้องกันความขัดแย้งเฉพาะสไตล์ ซึ่งจะเป็นประโยชน์อย่างยิ่งสำหรับฐานโค้ดขนาดใหญ่ ระบบการออกแบบ และเมื่อต้องจัดการสไตล์ของบุคคลที่สามในแอปพลิเคชัน
การจัดเรียง CSS ในลักษณะที่ชัดเจนจะช่วยป้องกันไม่ให้เกิดการลบล้างสไตล์ที่ไม่คาดคิดและส่งเสริมสถาปัตยกรรม CSS ที่ดีขึ้น
ความเฉพาะเจาะจงของ CSS และลําดับชั้น
ความเฉพาะเจาะจงของ CSS คือวิธีที่ CSS เลือกรูปแบบที่จะใช้กับองค์ประกอบใด ตัวเลือกต่างๆ ที่คุณใช้ได้จะกำหนดความเฉพาะเจาะจงของกฎสไตล์ เช่น องค์ประกอบมีความเฉพาะเจาะจงน้อยกว่าคลาสหรือแอตทริบิวต์ ซึ่งก็มีความเฉพาะเจาะจงน้อยกว่ารหัส นี่เป็นพื้นฐานสำคัญในการเรียนรู้ CSS
ผู้คนหันมาใช้รูปแบบการตั้งชื่อ CSS เช่น BEM เพื่อไม่ให้ลบล้างความเฉพาะเจาะจงโดยไม่ตั้งใจ การตั้งชื่อคลาสเดียวกันให้กับทุกอย่างจะทําให้ทุกอย่างอยู่ในระนาบความเฉพาะเจาะจงเดียวกัน อย่างไรก็ตาม การรักษาสไตล์ที่เป็นระเบียบเช่นนี้อาจทำได้ไม่เสมอไป โดยเฉพาะเมื่อต้องทำงานกับโค้ดและระบบการออกแบบของบุคคลที่สาม
เลเยอร์ Cascade มีไว้เพื่อแก้ปัญหานี้ โดยจะเพิ่มเลเยอร์ใหม่ในลำดับชั้น CSS เมื่อใช้สไตล์ที่วางซ้อนกัน ลำดับความสำคัญของเลเยอร์จะเหนือกว่าความเฉพาะเจาะจงของตัวเลือกเสมอ
เช่น ตัวเลือก .post a.link
มีความเฉพาะเจาะจงมากกว่า .card a
หากพยายามจัดรูปแบบลิงก์ภายในการ์ดในโพสต์ คุณจะเห็นว่ามีการใช้ตัวเลือกที่เฉพาะเจาะจงมากขึ้น
การใช้ @layer
จะช่วยให้คุณระบุความเฉพาะเจาะจงของสไตล์แต่ละรายการได้ชัดเจนยิ่งขึ้น และตรวจสอบว่าสไตล์ของลิงก์การ์ดลบล้างสไตล์ของลิงก์โพสต์ แม้ว่าความเฉพาะเจาะจงอาจลดลงหาก CSS ทั้งหมดอยู่ในระนาบเดียวกัน เนื่องจากลําดับความสำคัญของการแสดงผลตามลำดับขั้น สไตล์ที่วางซ้อนกันจะสร้าง "ระนาบ" ใหม่แบบเรียงซ้อน
@layer
กำลังดำเนินการ
ตัวอย่างนี้แสดงประสิทธิภาพของเลเยอร์ Cascade โดยใช้ @layer
มีลิงก์หลายรายการที่แสดงอยู่ โดยบางลิงก์ไม่มีการใช้ชื่อคลาสเพิ่มเติม ลิงก์หนึ่งมีคลาส .link
และอีกลิงก์หนึ่งมีคลาส .pink
จากนั้น CSS จะเพิ่มเลเยอร์ 3 เลเยอร์ ได้แก่ base
, typography
และ utilities
ดังนี้
@layer base {
a {
font-weight: 800;
color: red; /* ignored */
}
.link {
color: blue; /* ignored */
}
}
@layer typography {
a {
color: green; /* styles *all* links */
}
}
@layer utilities {
.pink {
color: hotpink; /* styles *all* .pink's */
}
}
สุดท้ายแล้ว ลิงก์ทั้งหมดจะเป็นสีเขียวหรือชมพู เนื่องจากแม้ว่า .link
จะมีความเฉพาะเจาะจงระดับตัวเลือกสูงกว่า a
แต่ก็มีสไตล์สีใน a
ใน @layer
ที่มีลําดับความสําคัญสูงกว่า a { color: green }
จะลบล้าง .link { color: blue }
เมื่อกฎสีเขียวอยู่ในเลเยอร์หลังกฎสีน้ำเงิน
ลําดับชั้นจะมีความสำคัญเหนือกว่าความเฉพาะเจาะจงขององค์ประกอบ
การจัดระเบียบเลเยอร์
คุณสามารถจัดระเบียบเลเยอร์ในหน้าเว็บโดยตรงตามที่แสดงด้านบน หรือจะจัดระเบียบที่ด้านบนของไฟล์ก็ได้
ลําดับเลเยอร์จะสร้างขึ้นเมื่อชื่อเลเยอร์แต่ละรายการปรากฏในโค้ดเป็นครั้งแรก
ซึ่งหมายความว่าหากคุณเพิ่มข้อมูลต่อไปนี้ไว้ที่ด้านบนของไฟล์ ลิงก์ทั้งหมดจะปรากฏเป็นสีแดง และลิงก์ที่มีคลาส .link
จะปรากฏเป็นสีน้ำเงิน
@layer utilities, typography, base;
เนื่องจากตอนนี้ลำดับเลเยอร์กลับกัน โดยให้สาธารณูปโภคอยู่ก่อนและฐานข้อมูลอยู่หลังสุด ดังนั้น กฎสไตล์ในเลเยอร์ base
จึงมีความเฉพาะเจาะจงสูงกว่ากฎสไตล์ในเลเยอร์การจัดรูปแบบตัวอักษรเสมอ ลิงก์เหล่านี้จะไม่เป็นลิงก์สีเขียวอีกต่อไป แต่จะเปลี่ยนเป็นสีแดงหรือน้ำเงิน
การจัดระเบียบการนําเข้า
อีกวิธีในการใช้ @layer
คือการใช้กับไฟล์ที่นำเข้า คุณทําเช่นนี้ได้โดยตรงเมื่อนําเข้าสไตล์โดยใช้ฟังก์ชัน layer()
ดังตัวอย่างต่อไปนี้
/* Base */
@import '../styles/base/normalize.css' layer(base); /* normalize or rest file */
@import '../styles/base/base.css' layer(base); /* body and base styles */
@import '../styles/base/theme.css' layer(theme); /* theme variables */
@import '../styles/base/typography.css' layer(theme); /* theme typography */
@import '../styles/base/utilities.css' layer(utilities); /* base utilities */
/* Layouts */
@import '../styles/components/post.css' layer(layouts); /* post layout */
/* Components */
@import '../styles/components/cards.css' layer(components); /* imports card */
@import '../styles/components/footer.css' layer(components); /* footer component */
ข้อมูลโค้ดด้านบนมี 3 เลเยอร์ ได้แก่ base
,layouts
และ components
ไฟล์การแปลงค่าให้เป็นมาตรฐาน ธีม และแบบอักษรใน base
โดยมีไฟล์ post
ใน layouts
และ cards
และ footer
อยู่ใน components
เมื่อนำเข้าไฟล์ ระบบจะสร้างอินสแตนซ์เลเยอร์โดยใช้ฟังก์ชันเลเยอร์ อีกวิธีหนึ่งคือการจัดระเบียบเลเยอร์ที่ด้านบนของไฟล์ โดยประกาศเลเยอร์ก่อนการนําเข้า
@layer base,
theme,
layouts,
components,
utilities;
ตอนนี้ลำดับที่คุณ@import
สไตล์จะไม่ส่งผลต่อลําดับเลเยอร์ เนื่องจากมีการสร้างลําดับไว้แล้วในอินสแตนซ์แรกของชื่อเลเยอร์ คุณจะไม่ต้องกังวลเรื่องนั้นอีกต่อไป คุณยังคงตั้งค่าไฟล์ที่นำเข้าไปยังเลเยอร์ที่ต้องการได้ แต่ระบบจะจัดลําดับไว้แล้ว
เลเยอร์และการแสดงผลตามลำดับขั้น
มาดูกันทีละขั้นว่าเลเยอร์มีการใช้งานอย่างไรเมื่อเกี่ยวข้องกับการแสดงผลตามลำดับขั้นที่กว้างขึ้น
ลําดับความสําคัญมีดังนี้
- User Agent ปกติ (ลําดับความสําคัญต่ำสุด)
- ผู้ใช้ภายใน @layer
- ผู้ใช้ภายในแบบปกติ
- ผู้เขียน @layers
- ผู้เขียนแบบปกติ
- ผู้เขียน !important
- ผู้เขียน @layer !important
- ผู้ใช้ในเครื่อง !important
- User Agent !important** (ลําดับความสําคัญสูงสุด)
คุณอาจสังเกตเห็นว่าสไตล์ @layer !important
กลับหัว รูปแบบที่ซ้อนกันจะมีลําดับความสําคัญสูงกว่า ไม่ใช่เฉพาะเจาะจงน้อยกว่ารูปแบบที่ไม่ซ้อนกัน (ปกติ) สาเหตุคือ !important
ทำงานแบบตามลำดับชั้น ซึ่งจะทำลายลำดับชั้นตามปกติในสไตล์ชีตและกลับความเฉพาะเจาะจงระดับเลเยอร์ตามปกติ (ลําดับความสําคัญ)
เลเยอร์ที่ซ้อนกัน
นอกจากนี้ คุณยังฝังเลเยอร์ภายในเลเยอร์อื่นๆ ได้ด้วย ตัวอย่างต่อไปนี้มาจากคำอธิบายเลเยอร์ Cascade จาก Miriam Suzanne
@layer default {
p { max-width: 70ch; }
}
@layer framework {
@layer default {
p { margin-block: 0.75em; }
}
p { margin-bottom: 1em; }
}
ในข้อมูลโค้ดด้านบน คุณสามารถเข้าถึง framework.default
โดยใช้ .
เป็นตัวบ่งชี้เลเยอร์ default
ที่ฝังอยู่ภายใน framework
คุณยังเขียนในรูปแบบที่สั้นลงได้ดังนี้
@layer framework.default {
p { margin-block: 0.75em }
}
เลเยอร์และลําดับเลเยอร์ที่ได้จะเป็นดังนี้
- ค่าเริ่มต้น
framework.default
framework
ยกเลิกการวางซ้อน- ไม่ได้ซ้อนทับ
สิ่งที่ควรระวัง
เลเยอร์ตามลําดับชั้นจะมีประโยชน์มากหากคุณใช้อย่างถูกต้อง แต่ก็อาจทําให้เกิดความสับสนและผลลัพธ์ที่ไม่คาดคิดได้เช่นกัน โปรดระวังสิ่งต่อไปนี้เมื่อทำงานกับเลเยอร์แคสเคด
กฎข้อที่ 1: อย่าใช้ @layer
เพื่อกําหนดขอบเขต
เลเยอร์ Cascade ไม่ได้ช่วยแก้ปัญหาการกําหนดขอบเขต หากคุณมีไฟล์ CSS ที่มี @layer
เช่น card.css
และต้องการกำหนดสไตล์ลิงก์ทั้งหมดภายในการ์ด อย่าเขียนสไตล์ดังนี้
a {
…
}
ซึ่งจะทำให้แท็ก a
ทั้งหมดในไฟล์ได้รับการลบล้างนี้ คุณยังคงต้องกําหนดขอบเขตสไตล์อย่างเหมาะสม
.card a {
…
}
กฎที่ 2: เลเยอร์ Cascading จะจัดเรียงไว้หลัง CSS ที่ไม่มีเลเยอร์
โปรดทราบว่าไฟล์ CSS แบบเลเยอร์จะไม่ลบล้าง CSS ที่ไม่มีเลเยอร์ เราตั้งใจที่จะทําเช่นนี้เพื่อให้นําเข้าเลเยอร์ได้ง่ายขึ้นด้วยวิธีที่สมเหตุสมผลมากขึ้นเพื่อทํางานกับโค้ดเบสที่มีอยู่ ตัวอย่างเช่น การใช้ไฟล์ reset.css
เป็นจุดเริ่มต้นและ Use Case ที่ยอดเยี่ยมสําหรับเลเยอร์แคสเคด
กฎ 3: !important
กลับความเฉพาะเจาะจงของการแสดงโฆษณาตามลำดับขั้น
แม้ว่าโดยทั่วไปแล้ว รูปแบบที่มีเลเยอร์จะเจาะจงน้อยกว่ารูปแบบที่ไม่มีเลเยอร์ แต่การใช้ !important
จะทําให้รูปแบบมีความละเอียดมากขึ้น ในการวางซ้อน การประกาศที่มีกฎ !important
จะเฉพาะเจาะจงมากกว่าสไตล์ที่ไม่มีการวางซ้อน
ในกรณีนี้ รูปแบบ !important
จะกลับความเฉพาะเจาะจง แผนภาพด้านบนแสดงข้อมูลนี้เพื่อเป็นข้อมูลอ้างอิง: author @layers มีลําดับความสําคัญต่ำกว่า author normal ซึ่งมีลําดับความสําคัญต่ำกว่า author !important ซึ่งมีลําดับความสําคัญต่ำกว่า author @layer !important
หากคุณมีเลเยอร์หลายเลเยอร์ เลเยอร์แรกที่มี !important
จะมีลําดับความสําคัญของ !important
มากกว่าและเป็นสไตล์ที่เฉพาะเจาะจงที่สุด
กฎข้อที่ 4: ทําความเข้าใจจุดฉีด
เนื่องจากระบบจะกำหนดลําดับเลเยอร์เมื่อชื่อเลเยอร์แต่ละชื่อปรากฏในโค้ดเป็นครั้งแรก หากคุณใส่การประกาศ @layer
หลังการนําเข้าและการตั้งค่า layer()
หรือหลังคำสั่ง @layer
อื่น ระบบจะไม่สนใจการประกาศนั้น ซึ่งต่างจาก CSS ที่ระบบจะใช้กฎสไตล์ที่อยู่ด้านล่างสุดของหน้าสำหรับเลเยอร์แคสเคด โดยระบบจะกำหนดลําดับตั้งแต่แรก
ซึ่งอาจเป็นรายการ ในบล็อกเลเยอร์ หรือในการนําเข้าก็ได้ หากคุณใส่ @layer
หลังรายการการนําเข้าที่มี layer()
ระบบจะไม่ทําการใดๆ การวางที่ด้านบนของไฟล์จะเป็นการกำหนดลําดับเลเยอร์ และช่วยให้คุณเห็นเลเยอร์ภายในสถาปัตยกรรมได้อย่างชัดเจน
กฎข้อ 5: ตรวจสอบความเฉพาะเจาะจง
เมื่อใช้เลเยอร์ตามลำดับชั้น ตัวเลือกที่เฉพาะเจาะจงน้อยกว่า (เช่น a
) จะลบล้างตัวเลือกที่เฉพาะเจาะจงมากกว่า (เช่น .link
) หากตัวเลือกที่เฉพาะเจาะจงน้อยกว่าอยู่ในเลเยอร์ที่มีความเฉพาะเจาะจงมากกว่า ลองพิจารณาสิ่งเหล่านี้
a
ใน layer(components)
จะลบล้าง .pink
ใน layer(utilities)
ในกรณีที่มีการระบุ @layer utilities, components
แม้ว่าจะเป็นส่วนหนึ่งที่ตั้งใจสร้างขึ้นของ API แต่การดำเนินการนี้อาจสร้างความสับสนและหงุดหงิดได้หากคุณไม่คาดคิด
ดังนั้น หากคุณเขียนคลาสยูทิลิตี ให้รวมไว้ในเลเยอร์ที่มีลําดับสูงกว่าคอมโพเนนต์ที่คุณต้องการลบล้างเสมอ คุณอาจคิดว่า "ฉันเพิ่งเพิ่มคลาส .pink
นี้เพื่อเปลี่ยนสี แต่ระบบไม่ใช้คลาสดังกล่าว"
ดูข้อมูลเพิ่มเติมเกี่ยวกับเลเยอร์ตามลําดับชั้น
นอกจากนี้ คุณยังดูข้อมูลเพิ่มเติมเกี่ยวกับเลเยอร์ตามลำดับขั้นได้จากแหล่งข้อมูลต่อไปนี้