HTML5 template: шаблоны разметки без рендера и лишнего JavaScript
Если вам нужно многократно добавлять на страницу одинаковые блоки — карточки товаров, сообщения чата, пункты списка, строки таблицы, — не обязательно собирать HTML длинными строками в JavaScript. Для этого в HTML5 есть тег <template>. Он хранит разметку в документе, но браузер не рендерит её до тех пор, пока вы сами не скопируете содержимое шаблона и не вставите его в нужное место.
Эта статья оптимизирована под запрос «HTML template пример» и показывает практический сценарий: создадим список товаров на основе HTML-шаблона.
Что делает тег template в HTML5
<template> — это контейнер для «спящей» разметки. Всё, что находится внутри него:
- не отображается на странице;
- не участвует в обычном потоке документа;
- не загружает изображения как видимый контент;
- становится доступным через свойство
template.contentв JavaScript.
Базовый пример выглядит так:
<template id="message-template">
<article class="message">
<h3 class="message__title"></h3>
<p class="message__text"></p>
</article>
</template>
Сам по себе этот код ничего не покажет пользователю. Чтобы вывести блок, нужно клонировать содержимое шаблона.
Практический пример: карточки товаров из template
Представим, что у нас есть массив товаров, и мы хотим вывести карточки в каталог. Сначала подготовим HTML-разметку: контейнер для результата и шаблон одной карточки.
<section class="catalog" aria-label="Каталог товаров">
<div class="catalog__grid" id="product-list"></div>
</section>
<template id="product-card-template">
<article class="product-card">
<img class="product-card__image" src="" alt="" width="300" height="200">
<h3 class="product-card__title"></h3>
<p class="product-card__price"></p>
<button class="product-card__button" type="button">В корзину</button>
</article>
</template>
Теперь добавим JavaScript, который берёт шаблон, клонирует его и заполняет данными.
const products = [
{
title: 'HTML и CSS: стартовый набор',
price: 990,
image: 'images/html-css.jpg'
},
{
title: 'JavaScript для верстальщика',
price: 1490,
image: 'images/js.jpg'
},
{
title: 'Адаптивная вёрстка',
price: 1290,
image: 'images/adaptive.jpg'
}
];
const list = document.querySelector('#product-list');
const template = document.querySelector('#product-card-template');
products.forEach((product) => {
const card = template.content.cloneNode(true);
const image = card.querySelector('.product-card__image');
const title = card.querySelector('.product-card__title');
const price = card.querySelector('.product-card__price');
image.src = product.image;
image.alt = product.title;
title.textContent = product.title;
price.textContent = `${product.price} ₽`;
list.append(card);
});
Ключевая строка здесь — template.content.cloneNode(true). Метод cloneNode(true) создаёт глубокую копию, то есть копирует не только сам контейнер, но и все вложенные элементы.
Почему template лучше, чем сборка HTML строками
Новички часто пишут так:
list.innerHTML += `
<article class="product-card">
<h3>${product.title}</h3>
<p>${product.price} ₽</p>
</article>
`;
Такой подход кажется коротким, но у него есть минусы:
- сложнее поддерживать большую разметку;
- выше риск XSS, если вставлять пользовательские данные через HTML;
- при
innerHTML +=браузер может пересоздавать уже существующие узлы; - HTML и логика смешиваются в одну нечитаемую строку.
С <template> структура остаётся в HTML, а JavaScript только подставляет данные. Это аккуратнее и ближе к компонентному мышлению.
Ускоряем вставку через DocumentFragment
Если элементов много, лучше сначала собрать их во фрагмент, а затем один раз добавить в DOM. Это снижает количество операций с реальной страницей.
const fragment = document.createDocumentFragment();
products.forEach((product) => {
const card = template.content.cloneNode(true);
card.querySelector('.product-card__title').textContent = product.title;
card.querySelector('.product-card__price').textContent = `${product.price} ₽`;
const image = card.querySelector('.product-card__image');
image.src = product.image;
image.alt = product.title;
fragment.append(card);
});
list.append(fragment);
Для маленьких списков разница почти незаметна, но для сотен элементов такой приём полезен.
Обработчики событий: где их добавлять
После клонирования шаблона можно назначить обработчик кнопке внутри карточки:
products.forEach((product) => {
const card = template.content.cloneNode(true);
const button = card.querySelector('.product-card__button');
card.querySelector('.product-card__title').textContent = product.title;
button.addEventListener('click', () => {
console.log(`Добавлен товар: ${product.title}`);
});
list.append(card);
});
Если карточек очень много, лучше использовать делегирование событий на контейнере, но для простых случаев прямой обработчик вполне понятен.
Важные советы по использованию template
- Не забывайте про
cloneNode(true). Если передатьfalse, вложенная разметка не скопируется. - Используйте
textContentдля текста. Это безопаснее, чем вставлять данные черезinnerHTML. - Заполняйте
altу изображений. Это важно для доступности и SEO. - Давайте шаблонам понятные id. Например,
product-card-template, а не простоtpl1. - Не помещайте в шаблон критически важный видимый контент. Пока JavaScript не выполнится, пользователь его не увидит.
Когда использовать HTML template
Тег <template> хорошо подходит для:
- карточек товаров и статей;
- сообщений в чате;
- уведомлений;
- строк таблицы;
- повторяющихся блоков интерфейса;
- простых виджетов без подключения фреймворка.
Если вы только осваиваете современную вёрстку и хотите уверенно понимать, где заканчивается HTML и начинается логика JavaScript, посмотрите практический курс «Вёрстка сайта с нуля 2.0»: он поможет системно прокачать базу и собирать страницы более осознанно.
Типичные ошибки новичков
Ошибка 1: пытаться искать элементы шаблона напрямую на странице.
// Неправильно: элемент внутри template не находится как обычный видимый блок
const title = document.querySelector('.product-card__title');
Искать элементы нужно внутри клонированного фрагмента:
const card = template.content.cloneNode(true);
const title = card.querySelector('.product-card__title');
Ошибка 2: вставлять пользовательский HTML без проверки. Если данные пришли от пользователя, используйте textContent, а не innerHTML.
Ошибка 3: забывать, что template не отображается без JavaScript. Для критичного контента лучше иметь серверную разметку или fallback.
Итог
<template> в HTML5 — простой и полезный инструмент для повторяющейся разметки. Он помогает держать HTML отдельно от логики, безопасно подставлять данные и создавать элементы интерфейса без тяжёлых библиотек. Для новичков это отличный шаг от статичной страницы к динамическому интерфейсу, а для продолжающих разработчиков — удобный способ писать чище и поддерживаемее.
-
Создано 18.09.2026 17:00:56
-
Михаил Русаков

Комментарии (0):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.