Клавиша / esc

.attachShadow()

Создаёт и прикрепляет Shadow DOM к элементу, позволяя инкапсулировать стили и разметку

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

Кратко

Скопировано

.attachShadow() — это метод, который позволяет создать и прикрепить Shadow DOM к HTML-элементу. Он используется в веб-компонентах для инкапсуляции структуры и стилей.

Пример

Скопировано
        
          
          <template id="my-box-template">  <style>    :host {      display: block;      padding: 1em;      background: lightgray;      border-radius: 6px;    }  </style>  <slot></slot></template><my-box>Содержимое бокса</my-box><script>class MyBox extends HTMLElement {  constructor() {    super()    const shadowRoot = this.attachShadow({ mode: 'open' })    const template = document.getElementById('my-box-template')    shadowRoot.appendChild(template.content.cloneNode(true))  }}customElements.define('my-box', MyBox)</script>
          <template id="my-box-template">
  <style>
    :host {
      display: block;
      padding: 1em;
      background: lightgray;
      border-radius: 6px;
    }
  </style>
  <slot></slot>
</template>

<my-box>Содержимое бокса</my-box>

<script>
class MyBox extends HTMLElement {
  constructor() {
    super()
    const shadowRoot = this.attachShadow({ mode: 'open' })
    const template = document.getElementById('my-box-template')
    shadowRoot.appendChild(template.content.cloneNode(true))
  }
}

customElements.define('my-box', MyBox)
</script>

        
        
          
        
      

Как пишется

Скопировано
        
          
          element.attachShadow({ mode: 'open' })
          element.attachShadow({ mode: 'open' })

        
        
          
        
      

Метод принимает объект с опциями:

  • mode: (обязательно) open (по умолчанию) или closed. В режиме open можно получить доступ к .shadowRoot извне. В closed — нет.
  • delegatesFocus: (опционально) true, если нужно передавать фокус внутрь компонента.
  • slotAssignment: (опционально) named или manual — режим работы со слотами (по умолчанию named).
  • clonable, serializable: (опционально) экспериментальные, пока редко используются.

Как понять

Скопировано

Если вы создаёте свой HTML-элемент (customElements.define(...)), то скорее всего захотите добавить Shadow DOM для:

  • изоляции CSS от внешней среды;
  • использования слотов (<slot>) для вставки содержимого;
  • лучшего контроля над внутренней структурой компонента.

Без вызова .attachShadow() компонент остаётся обычным элементом.

Анонимный компонент

Скопировано

Это такой компонент, который объявлен с помощью HTMLElement. Например:

        
          
          class MyBox extends HTMLElement { ... }customElements.define('my-box', MyBox)
          class MyBox extends HTMLElement { ... }

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

        
        
          
        
      

Но уже вот такой компонент НЕ считается анонимным:

        
          
          class MySection extends HTMLSectionElement { ... }customElements.define('my-section', MySection)
          class MySection extends HTMLSectionElement { ... }

customElements.define('my-section', MySection)

        
        
          
        
      

Он не считается анонимным из-за того, что он объявлен как HTML-элемент <section>.

Подсказки

Скопировано

💡 Shadow DOM — отличный способ инкапсуляции, но не подходит, если вам нужно, чтобы внешние стили влияли на компонент.
💡 Если Shadow DOM в режиме closed, то получить его через element.shadowRoot будет невозможно — даже из консоли.

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