การเรียงซ้อนเลเยอร์ (@layer
กฎ CSS) จะพร้อมใช้งานใน Chromium 99, Firefox 97 และ Safari 15.4 เบต้า โฆษณาประเภทนี้ช่วยให้ควบคุมไฟล์ CSS ของคุณได้ชัดเจนยิ่งขึ้นเพื่อป้องกันความขัดแย้งของสไตล์ที่เจาะจง ซึ่งมีประโยชน์มากโดยเฉพาะสำหรับโค้ดเบสขนาดใหญ่ ระบบออกแบบ และจัดการรูปแบบของบุคคลที่สามในแอปพลิเคชัน
การวางเลเยอร์ CSS อย่างชัดเจนช่วยป้องกันการลบล้างสไตล์ที่ไม่คาดคิดและส่งเสริมสถาปัตยกรรม CSS ที่ดีขึ้น
ความเฉพาะเจาะจง CSS และ Cascade
ความเฉพาะเจาะจงของ CSS คือวิธีที่ CSS ตัดสินใจเลือกรูปแบบที่จะใช้กับองค์ประกอบ ตัวเลือกรูปแบบต่างๆ ที่คุณใช้จะกำหนดความเฉพาะเจาะจงของกฎสไตล์ใดก็ได้ เช่น องค์ประกอบมีความเฉพาะเจาะจงน้อยกว่าคลาสหรือแอตทริบิวต์ ซึ่งก็มีความเฉพาะเจาะจงน้อยกว่ารหัส นี่คือองค์ประกอบสำคัญของการเรียนรู้ CSS
ผู้ใช้หันมาใช้แบบแผนการตั้งชื่อ CSS เช่น BEM เพื่อป้องกันการลบล้างความเฉพาะเจาะจงโดยไม่ได้ตั้งใจ เมื่อคุณตั้งชื่อคลาสเพียงชื่อเดียว ทุกอย่างจะปรากฏในระนาบที่เฉพาะเจาะจงเดียวกัน อย่างไรก็ตาม ก็อาจไม่สามารถคงไว้ซึ่งสไตล์ที่เป็นระเบียบเช่นนี้ได้ โดยเฉพาะเมื่อต้องทำงานกับโค้ดและระบบการออกแบบของบุคคลที่สาม
การเรียงซ้อนเลเยอร์มีจุดประสงค์เพื่อแก้ไขปัญหานี้ โดยได้แนะนำเลเยอร์ใหม่ให้กับการเรียงซ้อนของ CSS เมื่อใช้สไตล์แบบเลเยอร์ การให้ความสำคัญกับเลเยอร์จะเหนือกว่าความจำเพาะของตัวเลือกเสมอ
เช่น ตัวเลือก .post a.link
มีความเฉพาะเจาะจงสูงกว่า .card a
หากพยายามจัดรูปแบบลิงก์ คุณจะเห็นตัวเลือกที่เจาะจงมากขึ้นภายในการ์ดในโพสต์
เมื่อใช้ @layer
คุณจะระบุสไตล์ที่เจาะจงของสไตล์แต่ละรายการได้อย่างชัดเจนยิ่งขึ้น และตรวจสอบว่าสไตล์ของลิงก์การ์ดลบล้างรูปแบบของลิงก์โพสต์ แม้ว่าความเฉพาะเจาะจงอาจต่ำกว่าตัวเลขหาก CSS ทั้งหมดอยู่ในระนาบเดียวกัน เนื่องจากลำดับความสำคัญแบบ Cascade รูปแบบที่มีเลเยอร์จะสร้าง "เครื่องบิน" แบบ Cascade ใหม่
@layer
กำลังดำเนินการ
ตัวอย่างนี้แสดงถึงประสิทธิภาพของเลเยอร์การเรียงซ้อนโดยใช้ @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
สไตล์จะไม่สำคัญต่อลำดับเลเยอร์ เพราะระบบกำหนดรูปแบบไว้แล้วที่อินสแตนซ์แรกของชื่อเลเยอร์ นั่นคือเรื่องที่ต้องกังวลน้อยลงอีก 1 เรื่อง คุณยังคงสามารถตั้งค่าไฟล์ที่นำเข้าไปยังเลเยอร์ที่เฉพาะเจาะจงได้ แต่มีการกำหนดลำดับไว้แล้ว
เลเยอร์และน้ำตก
ลองย้อนกลับไปดูจุดที่มีการใช้เลเยอร์เนื่องจากมีความเกี่ยวข้องกับ Cascade ที่กว้างกว่า:
ลำดับความสำคัญมีดังนี้
- User Agent ปกติ (ลำดับความสำคัญต่ำสุด)
- ผู้ใช้ภายใน @layer
- ผู้ใช้ภายในปกติ
- ผู้เขียน @layers
- ผู้เขียนปกติ
- ผู้เขียน !important
- ผู้เขียน @layer !important
- ผู้ใช้ภายใน !important
- User Agent !important** (ลำดับความสำคัญสูงสุด)
คุณอาจเห็นว่ามีการกลับสไตล์ @layer !important
รูปแบบ แทนที่จะมีความเฉพาะเจาะจงน้อยกว่าสไตล์ที่ไม่ได้กำหนดเลเยอร์ (ปกติ) สไตล์จะมีความสำคัญสูงกว่า เนื่องจากวิธีการทำงานของ !important
ใน Cascade คือทำให้การ Cascad ปกติในสไตล์ชีตของคุณกลับคืนความจำเพาะระดับเลเยอร์ตามปกติ (ลำดับความสำคัญ)
เลเยอร์ที่ซ้อนกัน
เลเยอร์ยังสามารถซ้อนอยู่ภายในเลเยอร์อื่นๆ ได้ด้วย ตัวอย่างต่อไปนี้มาจากคำอธิบาย 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
เพื่อกำหนดขอบเขต
การเรียงซ้อนเลเยอร์ไม่สามารถแก้ไขขอบเขตได้ หากคุณมีไฟล์ CSS ที่มี @layer
เช่น card.css
และต้องการจัดรูปแบบลิงก์ทั้งหมดภายในการ์ด โปรดอย่าเขียนรูปแบบ เช่น
a {
…
}
ซึ่งจะทําให้แท็ก a
ทั้งหมดในไฟล์ได้รับการลบล้างนี้ คุณยังคงต้องกำหนดขอบเขตรูปแบบให้ถูกต้อง
.card a {
…
}
กฎข้อที่ 2: เลเยอร์การเรียงซ้อนจะเรียงลำดับอยู่หลัง CSS ที่ไม่ได้เลเยอร์
โปรดทราบว่าไฟล์ CSS ที่มีเลเยอร์จะไม่ลบล้าง CSS ที่ไม่ได้กำหนดเลเยอร์ การตัดสินใจนี้เกิดจากเจตนารมณ์ของการนำเลเยอร์ต่างๆ มาใช้เพื่อให้ทำงานร่วมกับฐานของโค้ดที่มีอยู่ได้อย่างมีประสิทธิภาพมากขึ้น ตัวอย่างเช่น การใช้ไฟล์ reset.css
เป็นจุดเริ่มต้นที่ดีและกรณีการใช้งานสำหรับ Cascade เลเยอร์ต่างๆ
กฎที่ 3: !important
กลับค่าความเฉพาะเจาะจงแบบ Cascade
แม้ว่ารูปแบบที่มีเลเยอร์จะเฉพาะเจาะจงน้อยกว่ารูปแบบที่ไม่มีเลเยอร์โดยทั่วไป แต่การใช้ !important
จะย้อนกลับสิ่งนี้ ในเลเยอร์ การประกาศที่มีกฎ !important
จะเจาะจงมากกว่าสไตล์ที่ไม่มีเลเยอร์
ในกรณีดังกล่าว รูปแบบ !important
จะกลับค่าความเฉพาะเจาะจง แผนภาพด้านบนแสดงการอ้างอิงนี้: ผู้เขียน @layers มีความสำคัญน้อยกว่าของผู้เขียนปกติ ซึ่งมีความสำคัญน้อยกว่าผู้เขียน !important ซึ่งมีความสำคัญน้อยกว่าผู้เขียน @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
นี้เพื่อเปลี่ยนสีแต่ตอนนี้ไม่ได้ใช้อยู่"
ดูข้อมูลเพิ่มเติมเกี่ยวกับเลเยอร์การเรียงซ้อน
คุณยังสามารถดูแหล่งข้อมูลเหล่านี้เพื่อเรียนรู้เพิ่มเติมเกี่ยวกับการเรียงซ้อนเลเยอร์: