Host Element และ Shadow Boundary
selector :host
หัวข้อที่มีชื่อว่า “selector :host”CSS selector :host กำหนดเป้าหมายไปที่ host element — element ที่เป็นเจ้าของ shadow root — จากภายใน shadow CSS นี่เป็นวิธีเดียวที่จะสไตล์ box model ของ host element เอง (display, border, padding) จาก shadow CSS ของ component
:host { display: inline-block; border: 2px solid #6366f1;}:host กับ selector
หัวข้อที่มีชื่อว่า “:host กับ selector”:host(selector) ใช้สไตล์เฉพาะเมื่อ host element ตรงกับ selector ที่ระบุ ซึ่งมีประโยชน์สำหรับการตอบสนองต่อ attribute หรือ class:
/* ใช้เมื่อ host element มี attribute highlight */:host([highlight]) { background: #fef08a; border-color: #ca8a04;}
/* ใช้เมื่อ host element มี class .large */:host(.large) { font-size: 1.25rem;}Shadow boundary และ events
หัวข้อที่มีชื่อว่า “Shadow boundary และ events”เมื่อ event เกิดขึ้นภายใน shadow tree และฟอง (bubble) ออกไปสู่ light DOM browser จะทำ event retargeting — event.target จะถูกเปลี่ยนเป็น host element แทนที่จะเป็น element จริงภายใน shadow tree ซึ่งป้องกันไม่ให้โค้ดภายนอกเห็น internal structure
Light DOM และ slots
หัวข้อที่มีชื่อว่า “Light DOM และ slots”Light DOM คือเนื้อหาที่วางไว้ภายใน element จากภายนอก — เนื้อหาที่ส่งเป็น children ให้ custom element สามารถ project เนื้อหา light DOM เข้าสู่ shadow tree ได้โดยใช้ <slot> elements
ตัวอย่างที่รันได้
หัวข้อที่มีชื่อว่า “ตัวอย่างที่รันได้”ข้อแลกเปลี่ยน
หัวข้อที่มีชื่อว่า “ข้อแลกเปลี่ยน”| ตัวเลือก | Benefit | Cost |
|---|---|---|
| Event retargeting ที่ shadow boundary | โค้ดภายนอกไม่เห็น internal structure ของ component ผ่าน event.target | debug event ยากขึ้น เพราะ event.target ที่ host ไม่ใช่ element จริงที่ถูกคลิกภายใน shadow tree |
สไตล์ host ผ่าน :host / :host() จากภายใน shadow CSS | component ควบคุม box model ของตัวเองได้ (display, border) โดยไม่ต้องพึ่งสไตล์ภายนอก | โค้ดภายนอกยังคง override บาง property จาก host element ได้ (เช่น inline style) ทำให้ผลลัพธ์ขึ้นกับใครเขียนทีหลัง |
ข้อผิดพลาดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ข้อผิดพลาดที่พบบ่อย”- คาดหวังว่า
event.targetในหน้าเว็บจะชี้ไปที่ element จริงภายใน shadow tree — เพราะ event retargeting จะเปลี่ยนevent.targetให้เป็น host element เสมอเมื่อ event ฟองออกมาถึง light DOM - ใช้ selector ธรรมดาแทน
:hostเพื่อสไตล์ตัว host element เอง — เขียนhost-badge { border: ... }ใน shadow CSS แล้วสงสัยว่าทำไมไม่ทำงาน ต้องใช้:hostเท่านั้นเพราะ host element อยู่นอก shadow tree - สับสนระหว่าง light DOM กับ shadow DOM — คิดว่าเนื้อหาที่ project ผ่าน
<slot>อยู่ใน shadow tree ทั้งที่จริงๆ light DOM content ยังคงเป็นของ caller และแก้ไขสไตล์จาก shadow root ไม่ได้โดยตรง
💡 ตัวอย่างจากของจริง
YouTube — video player component ใช้ event retargeting เพื่อให้โค้ดภายนอกจัดการ event ระดับ component (เช่น click ที่ player) โดยไม่ต้องรู้โครงสร้าง internal ของปุ่มควบคุมต่างๆ
Salesforce Lightning (LWC) — ใช้
:hoststyling อย่างเป็นระบบเพื่อให้ทุก component ควบคุม layout ของตัวเองได้โดยไม่ต้องพึ่ง global CSS ของหน้า