12k
All articles

Что входит в современный HTML-шаблон

Соберите современный HTML-шаблон с пятью обязательными строками, метаданными, фавиконами и тегами соцсетей. Узнайте, что оставить или удалить.

OpenReplay Team
OpenReplay Team
Что входит в современный 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.

Оставьте оба элемента <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, поэтому удаляйте это значение вручную или создайте собственный сниппет.

Open-source session replay

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

We use cookies to improve your experience. By using our site, you accept cookies.