หนึ่งในฟีเจอร์สำหรับผู้ประมวลผลข้อมูลล่วงหน้า CSS ที่เราชื่นชอบมีอยู่ในภาษาแล้ว นั่นคือการซ้อนกฎรูปแบบ
ก่อนการซ้อน ตัวเลือกทุกรายการต้องได้รับการประกาศอย่างชัดเจนโดยแยกจาก ซึ่งกันและกัน ซึ่งทำให้เกิดการทำซ้ำ สไตล์ชีตจำนวนมาก และการเขียนที่กระจัดกระจาย ประสบการณ์การใช้งาน
.nesting { color: hotpink; } .nesting > .is { color: rebeccapurple; } .nesting > .is > .awesome { color: deeppink; }
หลังจากการซ้อนตัวเลือก คุณอาจเลือก สามารถจัดกลุ่มกฎสไตล์ต่อเนื่องและที่เกี่ยวข้องไว้ภายในได้
.nesting { color: hotpink; > .is { color: rebeccapurple; > .awesome { color: deeppink; } } }
การฝังตัวช่วยเหลือนักพัฒนาซอฟต์แวร์ด้วยการลดความจำเป็นในการแนะนำตัวเลือกซ้ำไปพร้อมๆ กับ
กฎรูปแบบตำแหน่งร่วมสำหรับองค์ประกอบที่เกี่ยวข้อง นอกจากนี้ยังช่วยให้สไตล์สอดคล้องกับ
HTML ที่กำหนดเป้าหมาย หากคอมโพเนนต์ .nesting
ในตัวอย่างก่อนหน้านี้คือ
นำออกจากโปรเจ็กต์แล้ว คุณก็ลบกลุ่มทั้งกลุ่มแทนที่จะค้นหาได้
ไฟล์สำหรับอินสแตนซ์ของตัวเลือกที่เกี่ยวข้อง
การวางซ้อนมีประโยชน์สำหรับสิ่งต่างๆ ต่อไปนี้ - องค์กร - การลดขนาดไฟล์ - การเปลี่ยนโครงสร้างภายในโค้ด
การทำ Nest มีให้บริการใน Chrome 112 และยังลองใช้ใน Safari Technical Preview 162 ได้อีกด้วย
การเริ่มต้นใช้งาน CSS Nesting
ตลอดที่เหลือของโพสต์นี้ เราจะใช้แซนด์บ็อกซ์เดโมต่อไปนี้เพื่อช่วยคุณ ทำให้เห็นภาพของสิ่งที่เลือก ในสถานะเริ่มต้นนี้ จะไม่มีการเลือกใดๆ และ ทุกอย่างปรากฏให้เห็น เมื่อเลือกรูปร่างและขนาดต่างๆ คุณจะทำสิ่งต่อไปนี้ได้ ฝึกฝนไวยากรณ์และดูการทำงานจริง
ภายในแซนด์บ็อกซ์จะมีวงกลม สามเหลี่ยม และสี่เหลี่ยมจัตุรัส บ้างก็เล็กหรือปานกลาง
หรือใหญ่ ส่วนบางประเภทก็เป็นสีน้ำเงิน ชมพู หรือม่วง ทุกคนอยู่ใน .demo
ที่มีเอลิเมนต์ ต่อไปนี้เป็นตัวอย่างองค์ประกอบ HTML ที่คุณจะ
การกำหนดเป้าหมาย
<div class="demo">
<div class="sm triangle pink"></div>
<div class="sm triangle blue"></div>
<div class="square blue"></div>
<div class="sm square pink"></div>
<div class="sm square blue"></div>
<div class="circle pink"></div>
…
</div>
ตัวอย่างการซ้อน
การซ้อน CSS ช่วยให้คุณสามารถกำหนดรูปแบบสำหรับองค์ประกอบภายในบริบทของ อีกตัวเลือกหนึ่ง
.parent {
color: blue;
.child {
color: red;
}
}
ในตัวอย่างนี้ ตัวเลือกคลาส .child
ฝังอยู่ใน
ตัวเลือกคลาส .parent
ซึ่งหมายความว่าตัวเลือก .child
ที่ฝังไว้จะ
ใช้ได้กับองค์ประกอบที่เป็นองค์ประกอบย่อยขององค์ประกอบที่มีคลาส .parent
เท่านั้น
ตัวอย่างนี้อาจเขียนโดยใช้สัญลักษณ์ &
เพื่อ
ระบุว่าควรจัดชั้นเรียนหลักไว้ที่ใด
.parent {
color: blue;
& .child {
color: red;
}
}
ทั้ง 2 ตัวอย่างนี้มีฟังก์ชันการทำงานที่เทียบเท่ากันและเหตุผลที่คุณมีตัวเลือก จะมีความชัดเจนยิ่งขึ้นเมื่อคุณดูตัวอย่างขั้นสูงเพิ่มเติมในบทความนี้
การเลือกแวดวง
สำหรับตัวอย่างแรกนี้ งานคือการเพิ่มรูปแบบเพื่อจางลงและเบลอเฉพาะ ภายในการสาธิต
เมื่อไม่ได้ซ้อน CSS ในวันนี้จะดำเนินการดังนี้
.demo .circle {
opacity: .25;
filter: blur(25px);
}
การซ้อนทำได้ 2 วิธีดังนี้
/* & is explicitly placed in front of .circle */
.demo {
& .circle {
opacity: .25;
filter: blur(25px);
}
}
หรือ
/* & + " " space is added for you */
.demo {
.circle {
opacity: .25;
filter: blur(25px);
}
}
ผลลัพธ์ องค์ประกอบทั้งหมดใน .demo
ที่มีคลาส .circle
จะ
ภาพเบลอและแทบมองไม่เห็น:
การเลือกสามเหลี่ยมและสี่เหลี่ยมจัตุรัส
งานนี้ต้องเลือกองค์ประกอบที่ฝังหลายรายการ หรือเรียกอีกอย่างว่าตัวเลือกกลุ่ม
เมื่อไม่มีการซ้อน CSS ในปัจจุบันจะมี 2 วิธีดังนี้
.demo .triangle,
.demo .square {
opacity: .25;
filter: blur(25px);
}
หรือใช้ :is()
/* grouped with :is() */
.demo :is(.triangle, .square) {
opacity: .25;
filter: blur(25px);
}
การซ้อนมีวิธีที่ถูกต้อง 2 วิธีดังนี้
.demo {
& .triangle,
& .square {
opacity: .25;
filter: blur(25px);
}
}
หรือ
.demo {
.triangle, .square {
opacity: .25;
filter: blur(25px);
}
}
ผลลัพธ์ มีเพียง .circle
องค์ประกอบเท่านั้นที่ยังคงอยู่ภายใน .demo
:
การเลือกสามเหลี่ยมและวงกลมขนาดใหญ่
งานนี้ต้องใช้ตัวเลือกแบบผสม โดยที่ องค์ประกอบต้องมีทั้ง 2 คลาสจึงจะเลือกได้
เมื่อไม่ได้ซ้อน CSS ในวันนี้จะดำเนินการดังนี้
.demo .lg.triangle,
.demo .lg.square {
opacity: .25;
filter: blur(25px);
}
หรือ
.demo .lg:is(.triangle, .circle) {
opacity: .25;
filter: blur(25px);
}
การซ้อนมีวิธีที่ถูกต้อง 2 วิธีดังนี้
.demo {
.lg.triangle,
.lg.circle {
opacity: .25;
filter: blur(25px);
}
}
หรือ
.demo {
.lg {
&.triangle,
&.circle {
opacity: .25;
filter: blur(25px);
}
}
}
ผลลัพธ์ รูปสามเหลี่ยมขนาดใหญ่และวงกลมทั้งหมดจะซ่อนภายใน .demo
:
เคล็ดลับมือโปรเกี่ยวกับตัวเลือกแบบผสมและการซ้อน
สัญลักษณ์ &
คือเพื่อนของคุณที่นี่เนื่องจากแสดงให้เห็นอย่างชัดเจนถึงวิธี "แนบ" ที่ฝังไว้
ตัวเลือก ลองพิจารณาตัวอย่างต่อไปนี้
.demo {
.lg {
.triangle,
.circle {
opacity: .25;
filter: blur(25px);
}
}
}
แม้ว่าวิธีฝังที่ถูกต้องจะเป็นวิธีซ้อน แต่ผลการค้นหากลับไม่ตรงกับองค์ประกอบที่คุณคาดไว้
เหตุผลคือหากไม่มี &
เพื่อระบุผลลัพธ์ที่ต้องการของ .lg.triangle,
.lg.circle
ที่ประกอบเข้าด้วยกัน ผลลัพธ์จริงจะเป็น .lg .triangle, .lg
.circle
ตัวเลือกองค์ประกอบสืบทอด
เลือกรูปทรงทั้งหมดยกเว้นรูปสีชมพู
งานนี้ต้องใช้คลาสสมมติเกี่ยวกับฟังก์ชันนิเสธ โดยองค์ประกอบต้องไม่ มีตัวเลือกที่ระบุ
เมื่อไม่ได้ซ้อน CSS ในวันนี้จะดำเนินการดังนี้
.demo :not(.pink) {
opacity: .25;
filter: blur(25px);
}
การซ้อนมีวิธีที่ถูกต้อง 2 วิธีดังนี้
.demo {
:not(.pink) {
opacity: .25;
filter: blur(25px);
}
}
หรือ
.demo {
& :not(.pink) {
opacity: .25;
filter: blur(25px);
}
}
ผลลัพธ์ รูปร่างทั้งหมดที่ไม่ใช่สีชมพูจะซ่อนอยู่ใน .demo
:
ความแม่นยำและความยืดหยุ่นด้วย &
สมมติว่าคุณต้องการกำหนดเป้าหมาย .demo
ด้วยตัวเลือก :not()
ต้องระบุ &
สำหรับ
ซึ่ง:
.demo {
&:not() {
...
}
}
สารประกอบนี้ .demo
และ :not()
ถึง .demo:not()
ซึ่งตรงข้ามกับ
ตัวอย่างที่ต้องใช้ .demo :not()
การแจ้งเตือนนี้มีความสำคัญมากเมื่อ
ต้องการฝังการโต้ตอบ :hover
.demo {
&:hover {
/* .demo:hover */
}
:hover {
/* .demo :hover */
}
}
ตัวอย่างการฝังเพิ่มเติม
ข้อกำหนดของ CSS สำหรับการซ้อนคือ และตัวอย่างอีกมากมาย หากต้องการดูข้อมูลเพิ่มเติมเกี่ยวกับไวยากรณ์ ตัวอย่างทั้งหมดจะครอบคลุมตัวอย่างที่ถูกต้องและไม่ถูกต้องจำนวนมาก
ตัวอย่างเล็กๆ น้อยๆ ต่อไปนี้จะแนะนำฟีเจอร์ซ้อน CSS สั้นๆ เพื่อช่วยคุณ เข้าใจถึงความสามารถ ที่มีได้มากมาย
การฝัง @media
การไปยังส่วนอื่นๆ ของสไตล์ชีตอาจทำให้น่าเสียสมาธิมาก เงื่อนไขการค้นหาสื่อที่แก้ไขตัวเลือกและรูปแบบ สิ่งรบกวนนั้น อีกต่อไป ความสามารถในการฝังเงื่อนไขไว้ภายในบริบท
เพื่อความสะดวกด้านไวยากรณ์ หากคำค้นหาสื่อที่ฝังอยู่คือการแก้ไขรูปแบบเท่านั้น สำหรับบริบทตัวเลือกปัจจุบัน ก็สามารถใช้ไวยากรณ์แบบย่อได้
.card {
font-size: 1rem;
@media (width >= 1024px) {
font-size: 1.25rem;
}
}
การใช้ &
อย่างชัดแจ้งยังใช้ได้ด้วย:
.card {
font-size: 1rem;
@media (width >= 1024px) {
&.large {
font-size: 1.25rem;
}
}
}
ตัวอย่างนี้แสดงไวยากรณ์แบบขยายที่มี &
ในขณะที่กำหนดเป้าหมายเป็น .large
ด้วย
เพื่อแสดงฟีเจอร์การซ้อนเพิ่มเติมต่อไป
ดูข้อมูลเพิ่มเติมเกี่ยวกับการฝัง @rules
ซ้อนทุกตำแหน่ง
ตัวอย่างทั้งหมดจนถึงตอนนี้ยังคงปรากฏอยู่หรือต่อท้ายบริบทก่อนหน้า คุณสามารถเปลี่ยนหรือจัดเรียงบริบทใหม่ได้ตามต้องการ
.card {
.featured & {
/* .featured .card */
}
}
สัญลักษณ์ &
หมายถึงการอ้างอิงออบเจ็กต์ตัวเลือก (ไม่ใช่สตริง) และ
สามารถวางได้ทุกที่ในตัวเลือกที่ซ้อนกัน และยังสามารถวางได้หลายตำแหน่ง
เวลา:
.card {
.featured & & & {
/* .featured .card .card .card */
}
}
แม้ว่าตัวอย่างนี้จะดูไม่มีประโยชน์นัก แต่ก็มีบางสถานการณ์ที่ การอธิบายบริบทตัวเลือกซ้ำจึงมีประโยชน์
ตัวอย่างการซ้อนที่ไม่ถูกต้อง
มีบางสถานการณ์ไวยากรณ์การซ้อนที่ไม่ถูกต้องและอาจทำให้คุณประหลาดใจ หากคุณฝังอยู่ในตัวประมวลผลล่วงหน้า
การซ้อนและการเชื่อมต่อ
รูปแบบการตั้งชื่อคลาส CSS จำนวนมากต้องอาศัยการซ้อนที่สามารถเชื่อมโยงหรือ ต่อท้ายตัวเลือกเสมือนว่าเป็นสตริง วิธีนี้ไม่ทำงานในการซ้อน CSS เป็น ตัวเลือกไม่ใช่สตริง แต่เป็นการอ้างอิงออบเจ็กต์
.card {
&--header {
/* is not equal to ".card--header" */
}
}
ดูคำอธิบายที่ละเอียดยิ่งขึ้นได้ในข้อกำหนด
ตัวอย่างการซ้อนกันที่ซับซ้อน
ซ้อนกันภายในรายการตัวเลือกและ :is()
พิจารณาการบล็อก CSS ที่ซ้อนอยู่ต่อไปนี้
.one, #two {
.three {
/* some styles */
}
}
นี่เป็นตัวอย่างแรกที่ขึ้นต้นด้วยรายการตัวเลือก จากนั้นจึงซ้อนต่อไป ตัวอย่างก่อนหน้านี้สิ้นสุดด้วยรายการตัวเลือกเท่านั้น ตัวอย่างการซ้อนนี้ไม่มีสิ่งใดที่ไม่ถูกต้อง แต่ก็มีรายละเอียดการใช้งานที่อาจยุ่งยากเกี่ยวกับการซ้อนรายการตัวเลือก โดยเฉพาะรายการที่มีตัวเลือกรหัส
เพื่อให้ความตั้งใจของการซ้อนทำงานได้ เบราว์เซอร์จะรวมรายการตัวเลือกที่ไม่ใช่การซ้อนด้านในมากที่สุดด้วย :is()
การรวมนี้จะคงการจัดกลุ่มรายการตัวเลือกภายในบริบทใดก็ตามที่สร้างขึ้น ผลข้างเคียงของการจัดกลุ่มนี้ :is(.one, #two)
ก็คือการนำค่าที่เจาะจงของคะแนนสูงสุดภายในตัวเลือกภายในวงเล็บมาใช้ นี่คือวิธีที่ :is()
จะทำงานเสมอ แต่อาจไม่แปลกใจเมื่อใช้ไวยากรณ์การซ้อน เนื่องจากไม่ใช่สิ่งที่เขียนขึ้นทุกประการ สรุปเคล็ดลับแล้ว การซ้อนด้วยรหัสและรายการตัวเลือกอาจทำให้ตัวเลือกที่มีความเฉพาะเจาะจงสูงมาก
หากต้องการสรุปตัวอย่างที่ซับซ้อนให้ชัดเจน ระบบจะนำบล็อกที่ซ้อนกันก่อนหน้าไปใช้กับเอกสาร ดังนี้
:is(.one, #two) .three {
/* some styles */
}
คอยจับตาดูหรือสอนให้โปรแกรมวิเคราะห์โค้ดให้เตือนเมื่อซ้อนกันภายในรายการตัวเลือกที่ใช้ตัวเลือกรหัสอยู่ ความจำเพาะของการฝังทั้งหมดภายในรายการตัวเลือกนั้นจะสูง
การผสมการฝังและการประกาศ
พิจารณาการบล็อก CSS ที่ซ้อนอยู่ต่อไปนี้
.card {
color: green;
& { color: blue; }
color: red;
}
สีขององค์ประกอบ .card
จะเป็น blue
การประกาศรูปแบบแบบผสมจะยกไว้ด้านบน ราวกับว่า เขียนขึ้นก่อนที่จะมีการซ้อน ดูรายละเอียดเพิ่มเติมได้ในข้อกำหนด
ซึ่งมีอยู่หลายวิธีด้วยกัน ตัวอย่างต่อไปนี้จะรวมรูปแบบสี 3 รูปแบบใน &
ซึ่ง
รักษาการเรียงซ้อนตามแบบที่ผู้เขียนตั้งใจไว้ สีของ
องค์ประกอบ .card
จะเป็นสีแดง
.card {
color: green;
& { color: blue; }
& { color: red; }
}
อันที่จริงแล้ว คุณควรรวมสไตล์ใดๆ ก็ตามที่อยู่หลังการฝังด้วย &
.card {
color: green;
@media (prefers-color-scheme: dark) {
color: lightgreen;
}
& {
aspect-ratio: 4/3;
}
}
การตรวจหาฟีเจอร์
ฟีเจอร์การตรวจหา CSS ที่ซ้อนกันมี 2 วิธีที่ยอดเยี่ยม ได้แก่ ใช้การซ้อนหรือใช้
@supports
เพื่อตรวจสอบความสามารถในการแยกวิเคราะห์ตัวเลือกการซ้อน
การใช้การซ้อน
html {
.has-nesting {
display: block;
}
.no-nesting {
display: none;
}
}
กำลังใช้ @supports
:
@supports (selector(&)) {
/* nesting parsing available */
}
เพื่อนร่วมงานของฉัน Bramus มีCodepen ที่ยอดเยี่ยมที่แสดงกลยุทธ์นี้
การแก้ไขข้อบกพร่องด้วยเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome
การรองรับการฝังในเครื่องมือสำหรับนักพัฒนาเว็บในปัจจุบันมีน้อยมาก ปัจจุบันคุณจะพบ จะปรากฏในแผงรูปแบบตามที่คาดไว้ แต่การติดตามการซ้อน และยังไม่รองรับบริบทตัวเลือกทั้งหมด เรามีการออกแบบและวางแผนที่จะ ทำให้เรื่องนี้มีความโปร่งใสและชัดเจน
Chrome 113 วางแผนที่จะรองรับการฝัง CSS เพิ่มเติม โปรดอดใจรอ
อนาคต
CSS Nesting เป็นเวอร์ชัน 1 เท่านั้น เวอร์ชัน 2 จะเปิดตัวน้ำตาลแบบไวยากรณ์ที่มากขึ้น และกฎที่อาจมีน้อยลง จดจำ มีความต้องการจำนวนมากในการแยกวิเคราะห์การซ้อนเพื่อไม่จำกัด หรือมีช่วงเวลาที่ยุ่งยาก
การฝังเป็นการปรับปรุงครั้งใหญ่สำหรับภาษา CSS มีการสื่อความหมาย สถาปัตยกรรมของ CSS เกือบทั้งหมด การเปลี่ยนแปลงครั้งใหญ่นี้จะต้องอยู่อย่างลึกซึ้ง ที่สำรวจและทำความเข้าใจก่อนที่จะสามารถระบุเวอร์ชัน 2 ได้อย่างมีประสิทธิภาพ
เราขอแนะนำว่าลองดูการสาธิตนี้
ที่ใช้ @scope
, การซ้อน และ @layer
พร้อมกัน ทั้งหมดน่าตื่นเต้นมากเลย