• มีการเพิ่มอินเทอร์เฟซ 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 อยู่ก็อาจนำความสามารถนี้มาใช้ได้

ยังไม่มีความคิดเห็น

ยังไม่มีความคิดเห็น