Перейти к содержимому

Стилизация Shadow DOM

Добро пожаловать в наше подробное руководство по освоению стилизации Shadow DOM в JavaScript. В этом уроке мы подробно разберем особенности стилизации Shadow DOM, предоставив вам знания и навыки для эффективного использования этой мощной функции в ваших веб-проектах.

Понимание Shadow DOM

Прежде чем переходить к стилизации, давайте убедимся, что у нас есть четкое понимание того, что такое Shadow DOM. Shadow DOM (Shadow Document Object Model) — это веб-стандарт, позволяющий инкапсулировать DOM и CSS в отдельной изолированной области видимости. Он дает разработчикам возможность создавать компоненты с ограниченной областью видимости для стилей и функциональности, предотвращая утечку стилей и конфликты между различными частями веб-страницы. Также ознакомьтесь с предыдущей страницей в этой книге, Shadow DOM.

Создание Shadow DOM

Чтобы начать работу с Shadow DOM, сначала нужно его создать. Давайте посмотрим, как это сделать с помощью JavaScript:


html
<body>
  <div id="my-element"></div>
    <script>
      // Creating Shadow DOM
      const shadowRoot = document.getElementById('my-element').attachShadow({ mode: 'open' });
    
      // Styling Shadow DOM
      shadowRoot.innerHTML = `
        <p>A simple shadow root content.</p>
      `;
    </script>
</body>

В этом примере мы создаем элемент <div> с идентификатором "my-element" и прикрепляем к нему Shadow Root с помощью метода attachShadow(). Мы указываем режим 'open', что позволяет нам получать доступ к Shadow DOM и изменять его из JavaScript.

Стилизация Shadow DOM

WARNING

Сведите к минимуму смешение стилей между Shadow DOM и Light DOM, так как это может усложнить код и привести к потенциальным конфликтам.

После настройки Shadow DOM мы можем приступить к его стилизации для достижения желаемого внешнего вида. Стилизация Shadow DOM использует синтаксис, аналогичный обычному CSS, но с несколькими ключевыми отличиями:

Стили с ограниченной областью видимости

Стили, определенные внутри Shadow DOM, ограничены областью видимости именно этого Shadow-дерева, то есть они не повлияют на стили за его пределами. Давайте посмотрим, как мы можем применить стили к элементам внутри Shadow DOM:


html
<div id="my-element">
  <!-- Shadow DOM content -->
</div>

<script>
  const shadowRoot = document.getElementById('my-element').attachShadow({ mode: 'open' });

  shadowRoot.innerHTML = `
    <style>
      /* Scoped styles */
      :host {
        display: block;
        border: 2px solid #333;
        padding: 10px;
      }

      p {
        color: blue;
      }
    </style>

    <p>This paragraph is styled within the Shadow DOM.</p>
  `;
</script>

В этом примере мы определяем стили с ограниченной областью видимости внутри тега <style> в Shadow DOM. Псевдокласс :host нацелен на хост-элемент (в данном случае <div> с идентификатором "my-element"), что позволяет применять стили непосредственно к нему.

Стилизация контента в слотах

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


html
<body>
<script>
  class CustomButton extends HTMLElement {
    constructor() {
      super();
      const shadowRoot = this.attachShadow({ mode: 'open' });

      shadowRoot.innerHTML = `
        <style>
          :host {
            display: inline-block;
            padding: 10px 20px;
            background-color: #007bff;
            color: #fff;
            border: none;
            cursor: pointer;
          }

          :host(:hover) {
            background-color: #0056b3;
          }

          button {
            font-weight: bold;
            border: none;
            background: none;
            color: inherit;
            cursor: inherit;
            padding: 0;
          }

          /* Styling slotted content */
          ::slotted(span) {
            font-style: italic;
            text-decoration: underline;
          }
        </style>

        <button>
          <slot></slot>
        </button>
      `;
    }
  }

  customElements.define('custom-button', CustomButton);
</script>

<!-- Test custom-button with slotted content -->
<custom-button id="my-button">Click <span>here</span></custom-button>
</body>

В этом примере мы определяем пользовательский элемент <custom-button> со стилизацией Shadow DOM. Мы используем псевдоэлемент ::slotted() для нацеливания на <span> внутри слота. Стили применяются только к слотированному <span>, оставляя другой текст вне слота без изменений.

Заключение

Подводя итог, освоение стилизации Shadow DOM в JavaScript открывает широкие возможности для создания переиспользуемых и инкапсулированных веб-компонентов с ограниченной областью видимости стилей. Понимая принципы и методы, описанные в этом руководстве, вы будете хорошо подготовлены к эффективному использованию Shadow DOM в своих веб-проектах. Удачной разработки!

Практика

Какая функция Shadow DOM позволяет разработчикам стилизовать контент, проецируемый в пользовательские элементы?

Считаете ли это полезным?

Предпросмотр dual-run — сравните с маршрутами Symfony на продакшене.