Клавиша / esc

:host и :host()

Псевдоклассы :host и :host() позволяют стилизовать корневой элемент Shadow DOM компонента, в том числе с условиями на атрибуты.

Время чтения: меньше 5 мин

Кратко

Скопировано

Псевдокласс :host применяется внутри Shadow DOM и позволяет стилизовать корневой элемент (хост), к которому прикреплён Shadow DOM. Вариант с функцией :host(...) позволяет задать условие — например, стилизовать хост только если у него есть определённый атрибут или класс.

Пример

Скопировано
        
          
          <template id="my-box-template">  <style>    ::slotted(h1) {      color: #FF8630;    }    ::slotted(p) {      font-size: 1.2rem;    }    :host {      display: block;      padding: 1em;      border-radius: 5px;    }    :host(.warning) {      border-radius: 1.4rem;      border: 5px solid red;    }    :host([disabled]) {      opacity: 0.5;      pointer-events: none;    }  </style>  <div class="card" part="box">    <slot name="title">Пустая карточка 😔</slot>    <slot name="content"></slot>  </div></template><my-box>  <h1 slot="title">Крутая карточка 😎</h1>  <p slot="content">Контент очень крутого бокса</p></my-box><my-box class="warning">  <h1 slot="title">Внимание ⚠️</h1>  <p slot="content">Это предупреждающий бокс</p></my-box><my-box disabled>  <h1 slot="title">Отключённый бокс 🚫</h1>  <p slot="content">Этот бокс недоступен</p></my-box>
          <template id="my-box-template">
  <style>
    ::slotted(h1) {
      color: #FF8630;
    }

    ::slotted(p) {
      font-size: 1.2rem;
    }

    :host {
      display: block;
      padding: 1em;
      border-radius: 5px;
    }

    :host(.warning) {
      border-radius: 1.4rem;
      border: 5px solid red;
    }

    :host([disabled]) {
      opacity: 0.5;
      pointer-events: none;
    }
  </style>
  <div class="card" part="box">
    <slot name="title">Пустая карточка 😔</slot>
    <slot name="content"></slot>
  </div>
</template>

<my-box>
  <h1 slot="title">Крутая карточка 😎</h1>
  <p slot="content">Контент очень крутого бокса</p>
</my-box>

<my-box class="warning">
  <h1 slot="title">Внимание ⚠️</h1>
  <p slot="content">Это предупреждающий бокс</p>
</my-box>

<my-box disabled>
  <h1 slot="title">Отключённый бокс 🚫</h1>
  <p slot="content">Этот бокс недоступен</p>
</my-box>

        
        
          
        
      
        
          
          class MyBox extends HTMLElement {  constructor() {    super()    const shadow = this.attachShadow({ mode: 'open' })    const template = document.getElementById('my-box-template')    shadow.appendChild(template.content.cloneNode(true))  }}customElements.define('my-box', MyBox)
          class MyBox extends HTMLElement {
  constructor() {
    super()
    const shadow = this.attachShadow({ mode: 'open' })
    const template = document.getElementById('my-box-template')
    shadow.appendChild(template.content.cloneNode(true))
  }
}

customElements.define('my-box', MyBox)

        
        
          
        
      
Открыть демо в новой вкладке

Как пишется

Скопировано
  • :host — без параметров, просто селектор хоста.
        
          
          :host {  display: block;}
          :host {
  display: block;
}

        
        
          
        
      
  • :host(<селектор>) — селектор внутри скобок — условие на хост. Например:
        
          
          :host(.active) {  border-color: green;}:host([disabled]) {  opacity: 0.5;}
          :host(.active) {
  border-color: green;
}

:host([disabled]) {
  opacity: 0.5;
}

        
        
          
        
      

Можно использовать любые обычные CSS-селекторы, которые применимы к хост-элементу.

Как понять

Скопировано

Shadow DOM — это отдельный контекст, и в нём нельзя просто обратиться к хосту как к обычному элементу. Псевдокласс :host позволяет именно внутри Shadow DOM задать стили для самого хоста.

Использование условия через :host(...) даёт гибкость — можно менять стили компонента в зависимости от его атрибутов, классов или состояний, переданных извне.

Подсказки

Скопировано

💡 :host работает только внутри Shadow DOM. В обычном CSS вне компонента он не действует.
💡 Для выбора вложенных элементов компонента используется :host, ::slotted(...) и другие селекторы.
💡 Для стилизации частей компонента снаружи используйте part и ::part.
💡 :host и :host() имеют более низкую специфичность, чем внешние стили вне зависимости от селектора. Например:

        
          
          * {  padding: 0;  margin: 0;}
          * {
  padding: 0;
  margin: 0;
}

        
        
          
        
      
        
          
          <template>  <style>    :host {      /* Данное свойство будет ИГНОРИРОВАТЬСЯ        из-за низкой специфичности :host (или :host()) */      padding: 16px;    }  </style>  ...</template>
          <template>
  <style>
    :host {
      /* Данное свойство будет ИГНОРИРОВАТЬСЯ
        из-за низкой специфичности :host (или :host()) */
      padding: 16px;
    }
  </style>
  ...
</template>

        
        
          
        
      

💡 Псевдокласс :host() можно комбинировать с другими селекторами, например, :host(.enabled):hover. Или даже с другими псевдоклассами, такими как :not() и :is(), например:

        
          
          :host(:not([disabled])) { ... }:host(:is(:hover, :focus-visible)) { ... }:host(:dir(rtl)) { ... }
          :host(:not([disabled])) { ... }

:host(:is(:hover, :focus-visible)) { ... }

:host(:dir(rtl)) { ... }

        
        
          
        
      
Поддержка в браузерах:
  • Chrome 54, поддерживается
  • Edge 79, поддерживается
  • Firefox 63, поддерживается
  • Safari 10, поддерживается
О Baseline