- มีการเพิ่มอินเทอร์เฟซ
CSSNestedDeclarations เข้าไปในสเปกของ CSS Nesting ทำให้ปัญหาที่เกิดจากการซ้อนถูกแก้ไข
- นอกจากนี้ยังมีการปรับปรุงอื่น ๆ เช่น declaration ที่อยู่หลัง style rule จะไม่ถูกย้ายขึ้นไปด้านบนอีกต่อไป
- เริ่มมีผลตั้งแต่ Chrome 130, Firefox Nightly 132 และ Safari Technology Preview 204
ปัญหาของ CSS Nesting ก่อนการนำ CSSNestedDeclarations มาใช้
- มีปัญหาที่ declaration ที่ซ้อนอยู่ทำงานต่างจากที่คาดไว้
.foo {
width: fit-content;
@media screen {
background-color: red;
}
background-color: green;
}
- ใน Chrome เวอร์ชันก่อน 130
background-color จะถูกใช้เป็น red ไม่ใช่ green
- หลังการ parse แล้ว กฎที่ถูกนำไปใช้จริงจะเปลี่ยนเป็นดังนี้
.foo {
width: fit-content;
background-color: green;
@media screen {
& {
background-color: red;
}
}
}
background-color: green; จะถูกย้ายขึ้นไปด้านบนพร้อม declaration อื่น ๆ และ CSSMediaRule ที่ซ้อนอยู่จะถูกห่อด้วย CSSStyleRule เพิ่มเติมที่ใช้ตัวเลือก &
- สาเหตุคือ CSS engine ไม่สามารถแยกแยะ property ที่อยู่ต้น style rule ออกจาก property ที่อยู่ระหว่างกฎอื่น ๆ ได้
วิธีแก้ไข - การเพิ่มอินเทอร์เฟซ CSSNestedDeclarations
- CSS Working Group ได้เพิ่ม nested declarations rule เพื่อแก้ปัญหานี้
- ตั้งแต่ Chrome 130 เป็นต้นไป declaration ที่ซ้อนกันต่อเนื่องจะถูกห่อเป็นอินสแตนซ์ของ
CSSNestedDeclarations โดยอัตโนมัติ
- ด้วยวิธีนี้จึงสามารถคงตำแหน่งของ declaration
background-color: green ไว้หลัง declaration background-color: red ได้
CSSNestedDeclarations จะ match กับ element และ pseudo-element เดียวกับ parent style rule และมีพฤติกรรมด้าน specificity เหมือนกัน
ผลกระทบต่อผู้พัฒนา
- ตั้งแต่ Chrome 130 เป็นต้นไป CSS Nesting ได้รับการปรับปรุงอย่างมาก
- อย่างไรก็ตาม หากมีการผสม declaration กับ nested rule อาจต้องแก้ไขโค้ด
/* ใช้งานไม่ได้ใน Chrome 130 */
#mypopover:popover-open {
@starting-style {
opacity: 0;
scale: 0.5;
}
opacity: 1;
scale: 1;
}
- โค้ดด้านบนทำให้ declaration ใน
@starting-style ถูกเขียนทับด้วย declaration ที่อยู่ใน CSSNestedDeclarations จน entry animation หายไป
- ควรแก้เป็นดังนี้
/* ใช้งานได้ใน Chrome 130 */
#mypopover:popover-open {
opacity: 1;
scale: 1;
@starting-style {
opacity: 0;
scale: 0.5;
}
}
- หากใช้ CSS Nesting การวาง nested declaration ไว้เหนือ nested rule มักจะทำงานได้ดีในเบราว์เซอร์ส่วนใหญ่
การตรวจจับความสามารถของ CSSNestedDeclarations
if (!("CSSNestedDeclarations" in self && "style" in CSSNestedDeclarations.prototype)) {
// ไม่รองรับ CSSNestedDeclarations
}
ความเห็นของ GN⁺
- CSS Nesting เป็นฟีเจอร์ที่มีประโยชน์ ช่วยเพิ่มความอ่านง่ายและการดูแลรักษาโค้ด แต่ก่อนหน้านี้มีปัญหาจากการผสม nested rule กับ declaration ซึ่งการเพิ่ม
CSSNestedDeclarations ก็ช่วยแก้ปัญหานี้ได้
- ก่อนมี
CSSNestedDeclarations เคยมีปัญหาที่ตำแหน่งของ nested declaration เปลี่ยนไปหรือถูกเขียนทับโดยไม่ตั้งใจ ซึ่งเป็นจุดที่อาจทำให้นักพัฒนาสับสนได้
- เคยมีการพิจารณาวิธีแก้อื่น เช่น การใช้กฎ
@nest หรือการห่อ nested declaration ด้วย CSSStyleRule แต่ไม่ได้รับเลือกด้วยเหตุผลอย่างประสบการณ์การพัฒนาที่แย่ลง ดังนั้นการเพิ่ม nested declarations rule จึงดูเป็นทางออกที่เหมาะสมที่สุด
- อย่างไรก็ตาม
CSSNestedDeclarations ยังรองรับเฉพาะบางเบราว์เซอร์เท่านั้น ดังนั้นเพื่อการทำงานข้ามเบราว์เซอร์ การวาง nested declaration ไว้เหนือ nested rule เสมอยังคงเป็นทางเลือกที่ปลอดภัย
- CSS preprocessor อย่าง PostCSS และ Sass ก็มีฟีเจอร์คล้าย
CSSNestedDeclarations เช่นกัน หากใช้งาน preprocessor อยู่ก็อาจนำความสามารถนี้มาใช้ได้
ยังไม่มีความคิดเห็น