เชี่ยวชาญเกณฑ์ cascade ใหม่สองอย่าง คือ layers และ scope proximity เพื่อออกแบบสถาปัตยกรรมสไตล์ของคุณโดยไม่ต้องทำสงคราม specificity
เปิดบทเรียนนี้ใน Kodokoncascade แก้ไขข้อขัดแย้งของการประกาศต่าง ๆ โดยใช้เกณฑ์ที่เรียงลำดับไว้: origin และ importance, จากนั้นคือ context, แล้วสไตล์จากแอตทริบิวต์ style, จากนั้นคือ layers (@layer), แล้วจึงเป็น specificity และสุดท้ายคือลำดับการปรากฏ ประเด็นสำคัญคือ: layers ถูกประเมิน ก่อน specificity ดังนั้นกฎ .button ที่อยู่ในเลเยอร์ที่มีลำดับความสำคัญสูงกว่าจึงชนะ #nav div.menu a.button ที่อยู่ในเลเยอร์ที่ลำดับความสำคัญต่ำกว่า specificity ของมันที่ (1,2,2) ไม่มีความหมายเลยเมื่อเทียบกับลำดับของเลเยอร์ นี่คือสิ่งที่ทำให้ @layer ทรงพลังอย่างมากในการออกแบบสถาปัตยกรรม design system: ลำดับความสำคัญถูกประกาศเพียงครั้งเดียวในเชิงโครงสร้าง แทนที่จะต้องต่อสู้กันทีละเซเลกเตอร์
@layer reset, base, components, utilities;
@layer components {
.button { background: rebeccapurple; }
}
@layer base {
button { background: gray; }
}มีรายละเอียดปลีกย่อยในสเปกสองอย่างที่คุณจำเป็นต้องรู้อย่างยิ่ง อย่างแรก: สไตล์ที่อยู่ นอกเลเยอร์ใด ๆ จะชนะสไตล์ที่อยู่ในเลเยอร์ (สำหรับการประกาศแบบปกติ) เพราะมันก่อตัวเป็นเลเยอร์โดยปริยายที่ถูกวางไว้เป็นลำดับสุดท้าย ดังนั้นการเขียนทับในระดับท้องถิ่นของคุณจึงชนะไลบรารีที่ใช้เลเยอร์เสมอ อย่างที่สอง: เมื่อใช้ !important ลำดับจะ กลับด้านโดยสิ้นเชิง เลเยอร์ที่ถูกประกาศก่อนจะชนะ และ !important ภายในเลเยอร์จะชนะ !important ที่อยู่นอกเลเยอร์ใด ๆ การประกาศ !important ในเลเยอร์ reset ของคุณจึงแทบจะเอาชนะไม่ได้เลย
@layer base, theme;
@layer base {
a { color: black !important; }
}
@layer theme {
a { color: purple !important; }
}@scope จำกัดขอบเขตชุดของกฎไว้ระหว่าง scoping root และ ขอบเขตล่าง ที่ระบุหรือไม่ก็ได้: @scope (.card) to (.card__content) จะเล็งไปยังเอลิเมนต์ที่เป็นลูกหลานของ .card แต่อยู่นอก .card__content นี่คือ donut scope อันโด่งดัง ซึ่งเหมาะอย่างยิ่งสำหรับการจัดสไตล์กรอบของคอมโพเนนต์โดยไม่รั่วไหลเข้าไปในเนื้อหาที่ถูกฉีดเข้ามา ภายในขอบเขตนั้น :scope หมายถึงตัว root เอง และ @scope ยังนำเสนอเกณฑ์ cascade ใหม่เอี่ยม: proximity (ความใกล้) เมื่อ specificity เท่ากัน กฎที่มี scoping root อยู่ใกล้เอลิเมนต์มากที่สุดจะชนะ ซึ่งเป็นสิ่งที่ทั้ง BEM หรือ combinator ก็ไม่เคยแสดงออกมาได้
@scope (.card) to (.card__content) {
:scope {
padding: 1rem;
border: 1px solid oklch(0.85 0.02 260);
}
img { border-radius: 8px; }
}