ข้ามไปยังเนื้อหา

การ Encapsulate สไตล์

Shadow boundary คือเส้นกั้นที่ป้องกันไม่ให้ CSS รั่วผ่าน shadow root เส้นกั้นนี้ทำงานสองทิศทาง:

  • สไตล์ที่ประกาศ ภายใน shadow root จะไม่ส่งผลต่อ element ใดๆ ใน light DOM
  • selector CSS จาก ภายนอก shadow root ไม่สามารถกำหนดเป้าหมาย element ภายใน shadow tree ได้

ลักษณะนี้เรียกว่า style encapsulation และเป็นหนึ่งในคุณประโยชน์หลักของ Shadow DOM

ตัวอย่างด้านล่างกำหนด .box สองแบบ: หนึ่งในหน้า (สีน้ำเงิน) และอีกหนึ่งภายใน shadow root (สีแดง) เนื่องจาก shadow boundary แต่ละอันจะใช้เฉพาะกับ element ของตัวเอง

ตัวเลือกBenefitCost
Style encapsulation (shadow boundary)สไตล์ของ component ไม่ชนกับสไตล์หน้าโดยไม่ตั้งใจ ปลอดภัยต่อการนำไปใช้ซ้ำธีมจากภายนอกเข้าถึง internal ไม่ได้โดยตรง ต้องพึ่ง CSS custom properties หรือ ::part แทน
ไม่ใช้ Shadow DOM (global CSS ธรรมดา)ปรับสไตล์จากภายนอกได้อิสระ ไม่ต้องเปิด API เพิ่มเสี่ยง class name ชนกัน และสไตล์รั่วเข้า-ออกโดยไม่ตั้งใจเมื่อโปรเจกต์โต
  • คาดหวังให้ CSS หน้าเว็บ selector ธรรมดาเข้าไปสไตล์ภายใน shadow root ได้ — เช่นเขียน .my-widget .title { color: red } แล้วสงสัยว่าทำไมไม่ทำงาน shadow boundary ถูกออกแบบมาให้กันแบบนี้โดยเจตนา
  • ลืมว่า class name ข้างในและข้างนอก shadow root เป็นคนละ scope — ตั้ง .box ทั้งสองฝั่งแล้วคิดว่าต้องแก้ไขให้ไม่ชนกัน ทั้งที่จริงๆ ไม่ชนกันอยู่แล้วเพราะ encapsulation
  • ไม่รู้ว่ามี escape hatch อย่าง CSS custom properties และ ::part — พอ styling จากภายนอกไม่ได้เลยเลิกใช้ Shadow DOM ทั้งที่ควรออกแบบ custom property API ให้ theme ได้แบบควบคุมได้

💡 ตัวอย่างจากของจริง

Salesforce Lightning (LWC) — ใช้ style encapsulation เพื่อให้ component นับพันตัวจากทีมต่างๆ ไม่ชนสไตล์กันใน enterprise app ขนาดใหญ่

YouTube — video player component ใช้ encapsulation กันไม่ให้สไตล์ของหน้าเว็บ YouTube ที่เปลี่ยนบ่อยไปกระทบ UI ของ player

CSS ของหน้าประกาศ `.title { color: red; }` กฎนี้จะส่งผลต่อ element `.title` ภายใน shadow root หรือไม่?
shadow root มี `<style>p { font-size: 2rem; }</style>` กฎนี้ส่งผลต่อ element ใด?
อะไรที่สามารถข้าม shadow boundary ได้?
ประโยชน์หลักของ style encapsulation ใน Shadow DOM คืออะไร?