Работа с пользовательским контентом: тег <content> и <shadow> (Web Components)

🌟 Введение: Почему <content> и <shadow> — это круто

Web Components — это как конструктор LEGO для веба. А теги <content> и <shadow> — это волшебные кирпичики, которые помогают управлять содержимым и создавать изолированные стили.

🔹 Зачем это нужно?

  • Чтобы переиспользовать компоненты без костылей.
  • Чтобы стили не «убегали» за пределы компонента.
  • Чтобы создавать по-настоящему модульные интерфейсы.

🧩 <content>: Управляем вставкой контента

Тег <content> (из спецификации Shadow DOM v0, сейчас заменён на <slot>, но важно знать основы!) позволял «проецировать» внешний контент внутрь шаблона.

🛠️ Пример: Кастомная кнопка

<!-- 1. Объявляем шаблон -->
<template id="my-button">
  <style>
    button { background: #42b983; color: white; border: none; padding: 10px; }
  </style>
  <button>
    <content></content>  <!-- Сюда вставится переданный текст -->
  </button>
</template>

<!-- 2. Используем компонент -->
<my-button>Нажми меня!</my-button>

<script>
  const template = document.querySelector('#my-button');
  customElements.define('my-button', class extends HTMLElement {
    connectedCallback() {
      const shadowRoot = this.attachShadow({ mode: 'open' });
      shadowRoot.appendChild(template.content.cloneNode(true));
    }
  });
</script>

Что произошло?
1. В <content> подставился текст Нажми меня!.
2. Стили кнопки изолированы внутри Shadow DOM.


🕶️ <shadow>: Наследуем и дополняем

Тег <shadow> (устарел, но полезен для понимания) позволял обращаться к «старому» содержимому Shadow DOM при наследовании.

🔄 Пример: Расширение компонента

Допустим, у нас есть базовый компонент <cool-heading>, и мы хотим его улучшить:

<!-- Базовый компонент -->
<template id="cool-heading">
  <style> h1 { color: red; } </style>
  <h1><content></content></h1>
</template>

<!-- Улучшенная версия -->
<template id="super-heading">
  <style> h1 { text-shadow: 2px 2px 4px gray; } </style>
  <shadow></shadow>  <!-- Рендерим исходный h1 -->
  <small>Дополнительный текст</small>
</template>

<script>
  customElements.define('cool-heading', class extends HTMLElement {
    connectedCallback() {
      const shadowRoot = this.attachShadow({ mode: 'open' });
      shadowRoot.innerHTML = `
        <style>h1 { color: red; }</style>
        <h1><slot></slot></h1>
      `;
    }
  });

  // Переопределяем компонент
  const superTemplate = document.querySelector('#super-heading');
  customElements.define('super-heading', class extends HTMLElement {
    connectedCallback() {
      const shadowRoot = this.attachShadow({ mode: 'open' });
      shadowRoot.appendChild(superTemplate.content.cloneNode(true));
    }
  });
</script>

Итог:
<shadow> показывал исходное содержимое (красный h1).
— Поверх добавлялись новые стили и элементы (<small>).


💡 Современная альтернатива: <slot>

В Shadow DOM v1 <content> и <shadow> заменены на <slot>. Он мощнее и удобнее!

🎯 Пример с именованными слотами

<template id="user-card">
  <div class="card">
    <h2><slot name="username">Имя пользователя</slot></h2>
    <p><slot name="email">Email</slot></p>
  </div>
</template>

<!-- Использование -->
<user-card>
  <span slot="username">Данила Бежин</span>
  <span slot="email">danila@example.com</span>
</user-card>

Плюсы:
- Можно менять порядок вывода.
- Есть fallback-контент (если слот пуст).


📌 Главные выводы

  1. <content> — устаревший, но важный для понимания основ.
  2. <shadow> — позволял «наслаивать» Shadow DOM (теперь используйте композицию компонентов).
  3. <slot> — современный и гибкий инструмент для работы с контентом.

Для глубокого погружения в Web Components загляните на YouTube-канал Данилы Бежина — там есть разборы с живыми примерами!

Действие → Попробуйте создать свой компонент с <slot> и изолированными стилями. Это первый шаг к чистому и переиспользуемому коду! 🚀

Скрыть рекламу навсегда

🧠 Учёба без воды и зубрёжки

Закрытый Boosty с наработками опытного преподавателя.

Объясняю сложное так, чтобы щелкнуло.

🚀 Забрать доступ к Boosty