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

Selector :host

pseudo-class :host ช่วยให้คุณจัดสไตล์ตัว custom element เองจากภายใน shadow root ของตัวเอง มีสองรูปแบบที่คุณจะใช้เป็นประจำ บวกอีกหนึ่งรูปแบบที่ควรเลี่ยง:

  • :host — มีผลกับ host element เสมอ ไม่ว่าจะอยู่ในบริบทใด
  • :host(.modifier) — มีผลเฉพาะเมื่อ host element มี class ที่ระบุ
  • :host-context(selector) — มีผลเมื่อ ancestor ใดๆ ของ host ตรงกับ selector ที่กำหนด แต่อ่านคำเตือนด้านล่างก่อนเลือกใช้
:host { display: block; }
:host(.primary) { background: #3b82f6; }
:host-context(.dark-bg) { color: white; }

rule :host เป็นที่ที่เหมาะสมในการกำหนดการมีส่วนร่วมในเลย์เอาต์ของ element — ว่าจะ render เป็น block, inline-block, หรือ flex หากไม่กำหนด custom element จะมีค่าเริ่มต้นเป็น display: inline ซึ่งมักไม่ใช่สิ่งที่คุณต้องการ

รูปแบบแบบมีเงื่อนไข :host(.modifier) เป็นวิธีที่เป็นมาตรฐานในการจัดการ variants (primary, danger, small, large) โดยไม่ต้องใช้ JavaScript สลับสไตล์ภายใน รายการ class ของ host เป็นตัวขับเคลื่อนสไตล์ของ shadow

:host-context(selector) ดูน่าใช้สำหรับการทำ theming อัตโนมัติ — ปรับตัวเข้ากับ class ของ ancestor ที่เป็นโหมดมืดได้โดยที่หน้าไม่ต้องรู้ internals ของ component — แต่มันรองรับเฉพาะใน Chromium เท่านั้น ไม่เคยรองรับใน Firefox หรือ Safari และ CSS Working Group ได้ตัดออกจากสเปกไปแล้ว ให้ถือว่านี่เป็นฟีเจอร์เก่าที่ใช้ได้แค่ Chromium — อย่าใช้ในคอมโพเนนต์ใหม่ ใช้ CSS custom properties สำหรับ theming แทน (จะพูดถึงในบทถัดไป) หรือ @container style() container style query ในกรณีที่ไม่ต้องกังวลเรื่อง browser support กว้าง

ตัวเลือกBenefitCost
:host / :host()เขียนสไตล์ layout และ variants ของตัว component เองไว้ข้าง ๆ shadow tree โดยตรง ไม่ต้องพึ่ง class ภายนอกspecificity ต่ำกว่าสไตล์ของหน้าที่กำหนดเป้าหมาย element เดียวกันด้วย tag หรือ class ทำให้ page CSS override ได้ง่ายโดยไม่ตั้งใจ
:host-context()ปรับตัวตาม ancestor context (เช่น dark mode) ได้อัตโนมัติ โดยหน้าไม่ต้องรู้ internals ของ componentผูก component เข้ากับชื่อ class ของ ancestor ที่เฉพาะเจาะจง กลายเป็น dependency แบบซ่อนเร้นต่อโครงสร้างของหน้าที่ใช้งาน
  • คิดว่า :host ชนะสไตล์ของหน้าเสมอ — ลืมว่า :host มี specificity ต่ำกว่า selector ของหน้าที่กำหนดเป้าหมาย element เดียวกันโดยตรง เช่น badge-host { background: pink } จะ override :host { background: blue } แบบไม่คาดคิด
  • ใช้ :host-context() แทน custom properties เพื่อทำธีม — การผูก styling เข้ากับชื่อ class ของ ancestor ตรง ๆ ทำให้ component เปราะบางและย้ายไปใช้ในหน้าอื่นยาก ควรใช้ CSS custom properties สำหรับ theming ที่พกพาได้มากกว่า
  • ลืมกำหนด display บน :host — ไม่ตั้งค่า :host { display: ... } ตั้งแต่ต้น ทำให้ custom element มีค่าเริ่มต้นเป็น display: inline ซึ่งมักทำให้เลย์เอาต์เพี้ยนเมื่อฝังในหน้าจริง

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

Adobe Spectrum (Spectrum Web Components) — ใช้ :host ร่วมกับ CSS custom properties กำหนด layout เริ่มต้นของแต่ละ component ให้สอดคล้องกับ design system โดยไม่ต้องพึ่ง :host-context() ที่ผูกกับโครงสร้างหน้าตรง ๆ

Shoelace — ทุก component ตั้งค่า :host { display: ... } อย่างชัดเจนตั้งแต่ต้น เพื่อป้องกันปัญหา display: inline เริ่มต้นที่ทำให้เลย์เอาต์เพี้ยนเมื่อถูกฝังในหน้าจริง

:host ภายใน shadow root หมายถึงอะไร?
:host(.active) ใช้สไตล์เมื่อใด?
:host-context(dark-theme) ทำอะไร?