diff --git a/files/ru/web/html/element/template/index.md b/files/ru/web/html/element/template/index.md
index f6a818fd52cfd9..ab87e0a77f808d 100644
--- a/files/ru/web/html/element/template/index.md
+++ b/files/ru/web/html/element/template/index.md
@@ -1,31 +1,81 @@
---
title: ": элемент шаблона контента"
slug: Web/HTML/Element/template
+l10n:
+ sourceCommit: c749deb4ccb647d792deee4807d4852104bedd9d
---
{{HTMLSidebar}}
-[HTML](/ru/docs/Web/HTML)-элемент шаблона контента **``** — это механизм для отложенного создания клиентского контента, который не отображается во время загрузки страницы, но может быть инициализирован при помощи JavaScript.
+[HTML](/ru/docs/Web/HTML)-элемент шаблона контента **``** служит механизмом хранения фрагментов {{Glossary("HTML")}}, которые могут быть использованы позже при помощи JavaScript или немедленно сгенерированы в теневом DOM.
-Шаблон можно представить себе как фрагмент контента страницы, сохранённый для последующего использования в документе. Хотя парсер и обрабатывает содержимое элемента **``** во время загрузки страницы, он делает это, только чтобы убедиться в валидности содержимого, само содержимое при этом не отображается.
+## Атрибуты
-| [Категории контента](/ru/docs/Web/Guide/HTML/Content_categories) | [Метаданные](/ru/docs/Web/Guide/HTML/Content_categories#метаданные), [основной поток](/ru/docs/Web/Guide/HTML/Content_categories#основной_поток), [фразовый контент](/ru/docs/Web/Guide/HTML/Content_categories#phrasing_content), [элементы поддержки скриптов](/ru/docs/Web/Guide/HTML/Content_categories#элементы_поддержки_скриптов) |
-| ---------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| Допустимый контент | Нет ограничений |
-| Пропуск тегов | Нет, открывающий и закрывающий теги обязательны. |
-| Допустимые родители | Любые элементы, которые могут содержать [метаданные](/ru/docs/Web/Guide/HTML/Content_categories#метаданные), [фразовый контент](/ru/docs/Web/Guide/HTML/Content_categories#phrasing_content) или [элементы поддержки скриптов](/ru/docs/Web/Guide/HTML/Content_categories#элементы_поддержки_скриптов). Допускается вкладывать элемент в {{HTMLElement("colgroup")}}, у которого _отсутствует_ атрибут [`span`](/ru/docs/Web/HTML/Element/colgroup#span). |
-| Неявные ARIA-роли | [Нет соответствующей роли](https://www.w3.org/TR/html-aria/#dfn-no-corresponding-role) |
-| Допустимые ARIA-роли | Нет |
-| DOM-интерфейс | {{domxref("HTMLTemplateElement")}} |
+Этот элемент поддерживает [глобальные атрибуты](/ru/docs/Web/HTML/Global_attributes).
-## Атрибуты
+- `shadowrootmode`
+
+ - : Создает [теневой корень](/ru/docs/Glossary/Shadow_tree) для родительского элемента.
+ Это декларативная версия метода {{domxref("Element.attachShadow()")}} и принимает те же {{glossary("enumerated", "перечисляемые")}} значения.
+
+ - `open`
+
+ - : Открывает внутренний DOM теневого корня для JavaScript (рекомендуется для большинства случаев использования).
+
+ - `closed`
+
+ - : Скрывает внутренний DOM теневого корня от JavaScript.
+
+ > [!NOTE]
+ > HTML-парсер создает объект {{domxref("ShadowRoot")}} в DOM для первого `` в узле с установленным этим атрибутом на допустимое значение.
+ > Если атрибут не установлен или имеет недопустимое значение — или если `ShadowRoot` уже был создан декларативно в том же родительском узле — то создается {{domxref("HTMLTemplateElement")}}.
+ > {{domxref("HTMLTemplateElement")}} не может быть позже преобразован в теневой корень после разбора, например, путем установки {{domxref("HTMLTemplateElement.shadowRootMode")}}.
+
+ > [!NOTE]
+ > Вы можете найти нестандартный атрибут `shadowroot` в старых руководствах и примерах, которые ранее поддерживались в Chrome 90-110. Этот атрибут был удален и заменен стандартным атрибутом `shadowrootmode`.
+
+- `shadowrootclonable`
+
+ - : Устанавливает значение свойства [`clonable`](/ru/docs/Web/API/ShadowRoot/clonable) для [`ShadowRoot`](/ru/docs/Web/API/ShadowRoot), созданного с использованием этого элемента, в `true`.
+ Если установлен, клон теневого хоста (родительского элемента этого ``), созданный с помощью {{domxref("Node.cloneNode()")}} или {{domxref("Document.importNode()")}}, будет включать теневой корень в копию.
+
+- `shadowrootdelegatesfocus`
+
+ - : Устанавливает значение свойства [`delegatesFocus`](/ru/docs/Web/API/ShadowRoot/delegatesFocus) для [`ShadowRoot`](/ru/docs/Web/API/ShadowRoot), созданного с использованием этого элемента, в `true`.
+ Если установлен и выбран нефокусируемый элемент в теневом дереве, то фокус делегируется первому фокусируемому элементу в дереве.
+ Значение по умолчанию - `false`.
+
+- `shadowrootserializable` {{experimental_inline}}
+
+ - : Устанавливает значение свойства [`serializable`](/ru/docs/Web/API/ShadowRoot/serializable) для [`ShadowRoot`](/ru/docs/Web/API/ShadowRoot), созданного с использованием этого элемента, в `true`.
+ Если установлено, теневой корень может быть сериализован путем вызова методов {{DOMxRef('Element.getHTML()')}} или {{DOMxRef('ShadowRoot.getHTML()')}} с параметром `options.serializableShadowRoots`, установленным в `true`.
+ Значение по умолчанию - `false`.
+
+## Примечания по использованию
+
+Существует два основных способа использования элемента ``.
+
+### Фрагмент документа шаблона
-Элемент может иметь [общие атрибуты](/ru/docs/Web/HTML/Global_attributes).
+По умолчанию содержимое элемента не отображается.
+Интерфейс {{domxref("HTMLTemplateElement")}} включает стандартное свойство {{domxref("HTMLTemplateElement.content", "content")}} (без эквивалентного атрибута содержимого/разметки). Это свойство `content` является только для чтения и содержит {{domxref("DocumentFragment")}}, который представляет поддерево DOM, заданное шаблоном.
+Этот фрагмент можно клонировать с помощью метода {{domxref("Node.cloneNode", "cloneNode")}} и вставить в DOM.
-Однако у `{{domxref("HTMLTemplateElement")}}` есть свойство `{{domxref("HTMLTemplateElement.content", "content")}}`, которое возвращает доступный только для чтения `{{domxref("DocumentFragment")}}`, содержащий DOM-поддерево шаблона. Обратите внимание, что прямое использование значения `{{domxref("HTMLTemplateElement.content", "content")}}` может привести к непредсказуемому поведению, см. раздел [ловушка `DocumentFragment`](#avoiding_documentfragment_pitfall) ниже.
+Будьте осторожны при использовании свойства `content`, так как возвращаемый `DocumentFragment` может иметь неожиданные свойства.
+Для получения более подробной информации см. раздел [Избегание ошибок DocumentFragment](#avoiding_documentfragment_pitfalls) ниже.
+
+### Декларативный теневой DOM
+
+Если элемент `` содержит атрибут [`shadowrootmode`](#shadowrootmode) со значением `open` или `closed`, HTML-парсер немедленно создает теневой DOM. Элемент заменяется в DOM его содержимым, заключенным в {{domxref("ShadowRoot")}}, который присоединен к родительскому элементу.
+Это декларативный эквивалент вызова {{domxref("Element.attachShadow()")}} для присоединения теневого корня к элементу.
+
+Если элемент имеет другое значение для `shadowrootmode` или не имеет атрибута `shadowrootmode`, парсер создает {{domxref("HTMLTemplateElement")}}.
+Аналогично, если есть несколько декларативных теневых корней, только первый будет заменен на {{domxref("ShadowRoot")}} — последующие экземпляры будут разобраны как объекты {{domxref("HTMLTemplateElement")}}.
## Примеры
+### Генерация строк таблицы
+
Начнём с HTML.
```html
@@ -49,9 +99,9 @@ slug: Web/HTML/Element/template
```
-Для начала у нас есть таблица, в которую мы собираемся вставить контент с помощью Javascript. За таблицей следует шаблон, который описывает структуру HTML-фрагмента — строку таблицы.
+Для начала у нас есть таблица, в которую мы планируем вставить контент с помощью JavaScript. За таблицей расположен шаблон, который описывает структуру HTML-фрагмента — строку таблицы.
-Теперь, когда таблица была создана, а шаблон определён, используем JavaScript, чтобы вставить строки в таблицу. Каждая строка будет строиться по шаблону.
+После того как таблица создана и шаблон определён, мы используем JavaScript для вставки строк в таблицу. Каждая строка будет создаваться на основе шаблона.
```js
// Убеждаемся, что браузер поддерживает тег ,
@@ -59,19 +109,19 @@ slug: Web/HTML/Element/template
if ("content" in document.createElement("template")) {
// Находим элемент tbody таблицы
// и шаблон строки
- var tbody = document.querySelector("tbody");
- var template = document.querySelector("#productrow");
+ const tbody = document.querySelector("tbody");
+ const template = document.querySelector("#productrow");
// Клонируем новую строку и вставляем её в таблицу
- var clone = template.content.cloneNode(true);
- var td = clone.querySelectorAll("td");
+ const clone = template.content.cloneNode(true);
+ let td = clone.querySelectorAll("td");
td[0].textContent = "1235646565";
td[1].textContent = "Stuff";
tbody.appendChild(clone);
// Клонируем новую строку ещё раз и вставляем её в таблицу
- var clone2 = template.content.cloneNode(true);
+ const clone2 = template.content.cloneNode(true);
td = clone2.querySelectorAll("td");
td[0].textContent = "0384928528";
td[1].textContent = "Acme Kidney Beans 2";
@@ -96,9 +146,118 @@ table td {
{{EmbedLiveSample("Examples", 500, 120)}}
+### Реализация декларативного теневого DOM
+
+В этом примере скрытое предупреждение добавляется в начале разметки. Оно будет отображено через JavaScript, если браузер не поддерживает атрибут `shadowrootmode`. Далее следуют два элемента {{HTMLElement("article")}}, каждый из которых содержит вложенные элементы {{HTMLElement("style")}} с различным поведением. Первый `
+
Я нахожусь в DOM.
+
+
+
+
+
Я нахожусь в теневом DOM.
+
+
+```
+
+```js
+const isShadowRootModeSupported =
+ HTMLTemplateElement.prototype.hasOwnProperty("shadowRootMode");
+
+document
+ .querySelector("p[hidden]")
+ .toggleAttribute("hidden", isShadowRootModeSupported);
+```
+
+{{EmbedGHLiveSample("dom-examples/shadow-dom/shadowrootmode/scoping.html", "", "120")}}
+
+### Декларативный теневой DOM с делегированием фокуса
+
+Этот пример демонстрирует, как атрибут `shadowrootdelegatesfocus` применяется к теневому корню, созданному декларативно, и как это влияет на поведение фокуса.
+
+Вначале в элементе `
` создаётся теневой корень с использованием элемента `` и атрибута `shadowrootmode`.
+Внутри теневого корня размещается нефокусируемый `
` с текстом и фокусируемый элемент ``. Для стилизации элементов используется CSS: элементам с псевдоклассом [`:focus`](/ru/docs/Web/CSS/:focus) задаётся синий цвет, а также применяется базовая стилизация для элемента-хоста.
+
+```html
+
+
+
+
Кликабельный текст в теневом DOM
+
+
+
+```
+
+Второй блок кода идентичен, за исключением того, что он устанавливает атрибут `shadowrootdelegatesfocus`, который делегирует фокус первому фокусируемому элементу в дереве, если выбран нефокусируемый элемент в дереве.
+
+```html
+
+
+
+
Кликабельный текст в теневом DOM
+
+
+
+```
+
+Наконец, мы применяем следующий CSS, чтобы задать границу желто-зеленого цвета для родительского элемента `
` при его фокусировке."
+
+```css
+div:focus {
+ border: 2px solid red;
+}
+```
+
+Результаты показаны ниже.
+Когда HTML впервые отображается, элементы не имеют стилизации, как показано на первом изображении.
+Для теневого корня, у которого не установлен `shadowrootdelegatesfocus`, вы можете нажать в любом месте, кроме ``, и фокус не изменится (если выбрать элемент ``, он будет выглядеть как на втором изображении).
+
+![Скриншот кода без установленного фокуса](template_with_no_focus.png)
+
+Для теневого корня с установленным `shadowrootdelegatesfocus`, нажатие на текст (который не является фокусируемым) выбирает элемент ``, так как это первый фокусируемый элемент в дереве.
+Это также приводит к фокусировке родительского элемента, как показано ниже.
+
+![Скриншот кода с установленным фокусом](template_with_focus.png)
+
## Ловушка `DocumentFragment`
-{{domxref("DocumentFragment")}} не подходит в качестве целевого объекта для многих событий, поэтому предпочтительнее клонировать или ссылаться на элементы внутри него.
+Когда значение {{domxref("DocumentFragment")}} передается, методы {{domxref("Node.appendChild")}} и подобные перемещают только _дочерние узлы_ этого значения в целевой узел. Поэтому обычно предпочтительнее привязывать обработчики событий к дочерним элементам `DocumentFragment`, а не к самому `DocumentFragment`.
Рассмотрим следующие HTML-разметку и JavaScript-код:
@@ -108,7 +267,7 @@ table td {
-
Click me
+
Кликни на меня
```
@@ -119,24 +278,93 @@ const container = document.getElementById("container");
const template = document.getElementById("template");
function clickHandler(event) {
- event.target.append(" — Clicked this div");
+ event.target.append(" — Вы кликнули на этот div");
}
const firstClone = template.content.cloneNode(true);
firstClone.addEventListener("click", clickHandler);
container.appendChild(firstClone);
-const secondClone = template.content.firstElementChild.cloneNode(true);
-secondClone.addEventListener("click", clickHandler);
+const secondClone = template.content.cloneNode(true);
+secondClone.children[0].addEventListener("click", clickHandler);
container.appendChild(secondClone);
```
### Результат
-В переменной `firstClone` у нас экземпляр (клон) `DocumentFragment`, и хотя у нас получилось отрисовать его внутри контейнера, клик по нему не срабатывает. В переменной `secondClone` у нас экземпляр (клон) `{{domxref("HTMLDivElement")}}`, клик по которому работает как ожидается.
+Поскольку `firstClone` является `DocumentFragment`, только его дочерние элементы добавляются в `container` при вызове `appendChild`; обработчики событий `firstClone` не копируются. В отличие от этого, поскольку обработчик событий добавлен к первому _дочернему узлу_ `secondClone`, обработчик событий копируется при вызове `appendChild`, и клик по нему работает так, как ожидалось.
{{EmbedLiveSample('Avoiding_DocumentFragment_pitfall')}}
+## Техническая
+
+