Что входит в современный HTML-шаблон
Соберите современный HTML-шаблон с пятью обязательными строками, метаданными, фавиконами и тегами соцсетей. Узнайте, что оставить или удалить.
Современному базовому HTML-шаблону (boilerplate) нужны пять вещей: доктайп HTML5, атрибут lang у <html>, объявление кодировки UTF-8, метатег viewport и уникальный <title>. Всё остальное зависит от того, будут ли страницей делиться, устанавливать её как приложение или добавлять в закладки.
Большинство страниц начинается со сниппета ! из Emmet, файла index.html из фреймворка или копии HTML5 Boilerplate десятилетней давности. Эти строки никто не перепроверяет, поэтому устаревшие из них кочуют из проекта в проект.
В этой статье документ разобран построчно. Для каждой строки описано, что она делает, что ломается без неё и является ли она обязательной, необязательной или её можно смело удалить. О порядке элементов в <head> и метаданных в целом читайте в сопутствующей статье о том, что на самом деле должно находиться в head документа.
Вот что генерирует ! в Emmet:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
</html>
Это валидная отправная точка. Однако в ней нет description, canonical, тегов для соцсетей, иконок и color-scheme, а viewport содержит значение, которое больше не нужно.
Ключевые выводы
- Обязательные строки современного HTML-шаблона — доктайп,
lang,<meta charset="UTF-8">, тег viewport и<title>. Без любой из них страница отображается некорректно, становится менее доступной или невалидной. - Атрибут
langуправляет произношением в скринридерах, переносами в CSS и переводом в браузере. Google не использует его для определения языка страницы. maximum-scale,minimum-scaleиuser-scalable=noне дают слабовидящим пользователям масштабировать страницу. Удаляйте их везде, где встретите.- Полный набор фавиконок — это
favicon.ico,favicon.svg,apple-touch-icon.pngразмером 180×180 и веб-манифест с иконками 192 и 512 пикселей плюс маскируемой (maskable) иконкой. X-UA-Compatible,shrink-to-fit=noиtype="text/javascript"ничего полезного в новом проекте не делают, их можно удалить.
Доктайп и атрибут lang
Обязательно. <!DOCTYPE html> переключает браузер в стандартный режим. Без него HTML-парсер переходит в режим совместимости (quirks mode), который воспроизводит ошибки вёрстки старых браузеров. В результате появляются отличия в блочной модели и расчёте размеров таблиц, которые никакая отладка CSS не объяснит.
Обязательно. Атрибут lang у <html> выполняет три задачи:
- Сообщает скринридерам, какие правила произношения применять.
- Позволяет CSS-свойству
hyphens: autoпереносить слова по правильному словарю. - Помогает функциям перевода в браузере определить язык страницы.
Без него скринридер может читать французский текст с английской фонетикой. Значение — это языковой тег BCP 47, например en, de или pt-BR, и дочерние элементы могут его переопределять, как описано в справочнике MDN по lang.
lang отвечает за доступность и язык, а не за ранжирование в поиске. Google Search заявляет, что игнорирует lang и определяет язык по содержимому страницы.
<!DOCTYPE html>
<html lang="en">
Сначала charset, затем viewport
Обязательно. <meta charset="UTF-8"> должен находиться в пределах первых 1024 байт документа. Поэтому он идёт первым в <head> — раньше <title> и любого другого текста, который браузер иначе может декодировать в неверной кодировке. Если тег отсутствует или стоит слишком поздно, символы с диакритикой и эмодзи в заголовке превращаются в «кракозябры».
Обязательно. Тег viewport сообщает мобильным браузерам, что страницу нужно верстать по ширине устройства. Без него телефоны отрисовывают десктопную вёрстку (обычно шириной около 980px) и уменьшают её, поэтому ваши медиазапросы никогда не срабатывают. Самого по себе width=device-width достаточно, а initial-scale=1 обычно не нужен. Полный список значений см. в справочнике MDN по viewport.
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
Необязательно, сначала протестируйте. <meta name="text-scale" content="scale"> определён в черновике CSS Fonts Level 5 и поддерживается только браузерами на базе Chromium. Он заставляет корневой размер шрифта следовать размеру текста, выбранному пользователем в настройках ОС или браузера. В результате увеличивается только текст в rem и em, а компоненты с фиксированной высотой могут переполняться. Прежде чем выпускать это в продакшен, увеличьте системный размер текста и проверьте вёрстку.
Title, description и canonical
Обязательно. <title> задаёт название страницы во вкладках браузера, закладках, истории и результатах поиска. Если оставить значение по умолчанию Document, все открытые вкладки будут выглядеть одинаково.
Необязательно, но рекомендуется. <meta name="description"> предлагает краткое описание для поисковых сниппетов. Google может переписать его, если найдёт на странице текст, который лучше соответствует запросу, а обрезает сниппеты он по ширине отображения. Поэтому правила о количестве символов ненадёжны.
Необязательно, но рекомендуется. <link rel="canonical"> указывает предпочтительный URL, когда один и тот же контент доступен по нескольким адресам, например с query-параметрами или с косой чертой в конце и без неё. Подробнее см. в статье SEO-теги в HTML и как их оптимизировать.
<title>Page title – Site name</title>
<meta name="description" content="One or two sentences describing this page.">
<link rel="canonical" href="https://example.com/page">
Теги Open Graph и Twitter Card
Необязательно, но обязательно для всего, чем делятся. Теги Open Graph управляют превью ссылки в соцсетях и мессенджерах. Без них ссылка отображается как голый URL или как карточка, собранная из того, что найдёт скрейпер.
Протокол Open Graph называет обязательными свойства og:title, og:type, og:image и og:url и указывает, что страницу без типа следует считать website. Задайте og:url равным вашему каноническому URL, чтобы ссылки с параметрами отслеживания не кешировались как отдельные страницы. Для og:image Meta рекомендует изображение не меньше 1200×630 пикселей с соотношением сторон, близким к 1,91:1.
X читает собственные теги twitter:*, которые записываются через name, а не property, а при их отсутствии использует соответствующие значения og:*. На практике единственный специфичный для X тег, который вам нужен, — twitter:card, и то лишь если вы хотите карточку с крупным изображением.
<meta property="og:title" content="Page title">
<meta property="og:description" content="Description for link previews.">
<meta property="og:image" content="https://example.com/og-image.jpg">
<meta property="og:url" content="https://example.com/page">
<meta name="twitter:card" content="summary_large_image">
Чтобы сгенерировать эти теги для каждой страницы, воспользуйтесь генератором метатегов.
Набор фавиконок
Необязательно, но ожидаемо. Полный набор фавиконок состоит из четырёх частей. Без них вы получите пустую иконку вкладки, плитку в виде скриншота на домашнем экране iOS и стандартные иконки при установке на Android.
favicon.icoразмером 32×32 для старых браузеров.favicon.svg, который может подстраиваться подprefers-color-scheme. Safari поддерживает SVG-фавиконки начиная с Safari 26.0.apple-touch-icon.pngразмером 180×180 для домашнего экрана iOS.- Манифест веб-приложения с PNG-иконками 192×192 и 512×512, а также маскируемым вариантом для круглых и «сквиркл»-масок.
Оставьте оба элемента <link rel="icon"> — и для favicon.ico, и для favicon.svg. Тогда браузеры, не умеющие работать с SVG-фавиконками, включая Safari до 26-й версии, всё равно получат ICO-файл.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<style>
circle { fill: #1a1a2e; }
@media (prefers-color-scheme: dark) {
circle { fill: #f5f5f5; }
}
</style>
<circle cx="16" cy="16" r="14"/>
</svg>
{
"name": "Site name",
"short_name": "Site",
"icons": [
{ "src": "/icon-192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "/icon-512.png", "sizes": "512x512", "type": "image/png" },
{ "src": "/icon-maskable-512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
]
}
Подробнее о создании каждого файла см. в статье Как добавить фавиконку на сайт.
color-scheme и theme-color
Необязательно, рекомендуется, если у вас есть тёмная тема. <meta name="color-scheme" content="light dark"> сообщает браузеру, что страница поддерживает оба режима, ещё до загрузки CSS. Фон по умолчанию, элементы форм и полосы прокрутки тогда следуют предпочтениям пользователя. Без этого тега сайт с тёмной темой может при загрузке «вспыхнуть» белым фоном. См. MDN о color-scheme.
Необязательно. theme-color окрашивает интерфейс браузера и принимает атрибут media, так что можно задать отдельные значения для светлой и тёмной темы. Он работает в Chromium на Android, но MDN указывает поддержку браузерами как ограниченную, поэтому считайте его приятным дополнением, а не тем, что отобразит каждый браузер.
<meta name="color-scheme" content="light dark">
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#111111" media="(prefers-color-scheme: dark)">
Базовое правило для уменьшения анимации
Необязательно, настоятельно рекомендуется. Правило для уменьшения анимации относится к базовой таблице стилей, а не к тегам в head. Его место в шаблоне, потому что потом его никто не добавит. Блок prefers-reduced-motion: reduce сокращает анимации и переходы и отключает плавную прокрутку для пользователей, которые попросили операционную систему уменьшить движение.
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
Длительность задана как 0.01ms, а не 0, чтобы события animationend и transitionend всё равно срабатывали. Так JavaScript, ожидающий этих событий, не зависнет. Это грубое правило по умолчанию. Отдельные компоненты могут снова включить мягкую анимацию, например плавное изменение прозрачности, которая не вызывает вестибулярных проблем.
Какие строки удалить из старых шаблонов?
Удалить. Четыре строки в старых HTML-шаблонах достались в наследство от шаблонов эпохи IE и ранних адаптивных стартеров, и ни одна из них сегодня не делает ничего полезного:
X-UA-Compatibleвыбирал режим документа в Internet Explorer. Ни один из поддерживаемых вами браузеров его не читает.maximum-scale,minimum-scaleиuser-scalable=noне позволяют слабовидящим людям масштабировать страницу жестом, что противоречит критерию WCAG 1.4.4 «Изменение размера текста». Удалите их из всех тегов viewport.shrink-to-fit=noобходил старое поведение масштабирования в iOS Safari и больше ни на что не влияет.type="text/javascript"повторяет значение по умолчанию. Спецификация HTML рекомендует авторам не указыватьtypeдля классических скриптов.
<!-- Before -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, shrink-to-fit=no">
<script type="text/javascript" src="/app.js"></script>
<!-- After -->
<meta name="viewport" content="width=device-width">
<script type="module" src="/app.js"></script>
Скрипт с type="module" по умолчанию отложенный, поэтому выполняется после парсинга, не блокируя отрисовку. Если скрипт не может быть модулем, добавьте ему defer.
Полный HTML-шаблон
Ниже приведён полный современный HTML-шаблон, объединяющий все обязательные и рекомендуемые строки из этой статьи. При необходимости добавляйте поверх него специфичные для сайта элементы, например фиды или preload. Ссылка для пропуска навигации (skip link) и ориентир <main> размещаются в body, а о семантических элементах, которые идут дальше, рассказывается в статье 10 основных HTML-элементов.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<!-- Optional, test with large OS text first: <meta name="text-scale" content="scale"> -->
<title>Page title – Site name</title>
<meta name="description" content="One or two sentences describing this page.">
<link rel="canonical" href="https://example.com/page">
<meta name="color-scheme" content="light dark">
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#111111" media="(prefers-color-scheme: dark)">
<link rel="stylesheet" href="/styles.css">
<script type="module" src="/app.js"></script>
<link rel="icon" href="/favicon.ico">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<link rel="manifest" href="/site.webmanifest">
<meta property="og:title" content="Page title">
<meta property="og:description" content="Description for link previews.">
<meta property="og:image" content="https://example.com/og-image.jpg">
<meta property="og:url" content="https://example.com/page">
<meta name="twitter:card" content="summary_large_image">
</head>
<body>
<a href="#main">Skip to content</a>
<main id="main"></main>
</body>
</html>
| Строка | Что делает | Что ломается без неё | Вердикт |
|---|---|---|---|
| Доктайп | Стандартный режим | Вёрстка в режиме совместимости | Обязательно |
lang | Произношение, переносы, перевод | Неправильный голос скринридера | Обязательно |
charset | Объявляет UTF-8 | Искажённые символы | Обязательно |
viewport | Вёрстка по ширине устройства | Уменьшенная десктопная вёрстка на телефонах | Обязательно |
<title> | Задаёт название страницы | Одинаковые вкладки и закладки | Обязательно |
| Description, canonical | Сниппет и предпочтительный URL | Слабые сниппеты, дублирующиеся URL | Необязательно |
Open Graph, twitter:card | Превью ссылок | Голые или шаблонные карточки | Необязательно |
| Набор фавиконок | Иконки вкладки и домашнего экрана | Пустые иконки или скриншоты | Необязательно |
color-scheme | Нативная тёмная тема | Белая вспышка, светлые элементы управления | Необязательно |
X-UA-Compatible, ограничения масштаба, shrink-to-fit, type="text/javascript" | Устаревшие обходные решения | Ничего | Удалить |
Обязательны в HTML-шаблоне всего пять строк. Всё остальное либо необязательно — в зависимости от того, будут ли страницей делиться, устанавливать её или применять к ней темы, — либо является устаревшей строкой, которую нужно удалить. Откройте index.html своего текущего проекта, сверьте каждую строку с таблицей выше и удалите всё, что попадает в строку «Удалить», прежде чем копировать файл в следующий проект.
Часто задаваемые вопросы
meta charset — это то же самое, что meta http-equiv Content-Type?
Да. Согласно спецификации WHATWG HTML, вариант с http-equiv Content-Type выполняет ту же задачу, что и атрибут charset. Оба считаются объявлением кодировки символов, и оба должны находиться в пределах первых 1024 байт. Документ не должен содержать оба варианта одновременно — валидаторы помечают это как ошибку. Используйте более короткий meta charset='UTF-8'. Если сервер передаёт charset в HTTP-заголовке Content-Type, убедитесь, что там тоже указан UTF-8.
Нужна ли косая черта в конце тегов meta и link в HTML?
Нет. У meta, link, img и других пустых (void) элементов нет закрывающего тега, и HTML-парсер игнорирует косую черту в конце. Тег с косой чертой и тот же тег без неё создают одинаковый элемент. Косая черта допустима, но ни на что не влияет, так что это вопрос стиля. Значение она имеет только для страницы, отдаваемой как XHTML с MIME-типом XML.
Можно ли не писать теги html, head и body?
Да. Спецификация HTML во многих случаях помечает теги html, head и body как необязательные, и парсер создаёт эти элементы даже при отсутствии тегов. Тем не менее в шаблоне их стоит прописывать явно. Атрибуту lang нужен явный открывающий тег html, к которому его можно прикрепить, а явные теги делают границу между head и body наглядной. Если опустить тег html, вы лишитесь и lang.
Как изменить значение lang по умолчанию в сниппете ! из Emmet?
Задайте переменную lang в настройке emmet.variables в VS Code. В settings.json добавьте в объект emmet.variables ключ lang со значением, например, de — и Emmet будет подставлять этот код языка при каждом раскрытии сниппета !. В той же настройке есть переменная charset, её следует оставить равной UTF-8. Строка viewport по-прежнему будет содержать initial-scale=1.0, поэтому удаляйте это значение вручную или создайте собственный сниппет.
Gain control over your UX
See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.
Star on GitHub12k