Типы контента
Автор: Хаметов Артем
Как понять, когда вложенность допустима, а когда нарушает спецификацию?
Разберём на примерах и системно объясним, как работают категории контента в HTML и как определить допустимость вложенности по спецификации.
Пример 1. Ошибка: кнопка внутри ссылки
<a href=”#”>
<button>Нажми</button>
</a>
Элемент <a> относится к категории interactive content и принимает только phrasing content. Элемент <button> тоже интерактивный, и спецификация HTML прямо запрещает вложение одного интерактивного элемента в другой. В результате такое вложение считается ошибкой. Поведение может быть непредсказуемым: одни браузеры проигнорируют внутреннюю кнопку, другие — выведут предупреждение в консоли.
Пример 2. Ошибка: ссылка внутри кнопки
<button>
<a href=“/path”>Перейти</a>
</button>
Элемент <button> допускает только phrasing content, но не должен содержать интерактивные элементы. Ссылка <a> — это интерактивный элемент, и её вложение внутрь кнопки нарушает правило “нельзя вкладывать интерактив в интерактив”. Поведение будет аналогично предыдущему примеру — ошибка в спецификации и непредсказуемость в браузере.
Пример 3. Допустимо: ссылка в div
<div>
<a href=“/about”>О нас</a>
</div>
Элемент <div> относится к категории flow content и может содержать большинство других элементов, включая ссылки. А <a> — это phrasing и interactive content, и он допускается внутри flow-контейнеров. Такое вложение полностью соответствует правилам и работает корректно.
1. Metadata content
Назначение: Элементы, описывающие метаинформацию о документе. Используются только внутри <head>. Они не отображаются на странице напрямую, но влияют на поведение документа, подключают стили, скрипты и устанавливают общие параметры.
Примеры тегов:
<title>, <base>, <link>, <meta>, <style>, <script>, <noscript>
Где можно использовать:
- Только внутри <head>
Что можно вложить внутрь:
-
<script> и <style> могут содержать текст или код.
-
Остальные — пустые или с определёнными атрибутами (например, <meta charset=“UTF-8”>).
Нельзя:
- Использовать в <body>
- Вкладывать в них другие структурные элементы (<div>, <p>, и т.п.)
2. Flow content
Назначение: Основная категория, объединяющая всё, что может находиться внутри <body>. Это общее множество, куда входят почти все визуальные элементы.
Содержит подкатегории:
- Sectioning content
- Heading content
- Phrasing content
- Embedded content
- Interactive content
- И другие блоки (<div>, <form>, <table>, и т.д.)
Примеры тегов:
<section>, <article>, <p>, <div>, <h1>, <form>, <ul>, <table>, <blockquote>
Где можно использовать:
-
Внутри <body>
-
В других элементах flow-контента
Что можно вложить внутрь:
- Любой flow-контент
Нельзя:
- Вложить внутрь некоторых ограниченных тегов (например, нельзя вкладывать div внутрь p — div недопустим внутри phrasing-контента)
3. Sectioning content
Назначение: Делит документ на логические разделы. Каждый элемент этой категории начинает новый уровень в структуре документа (outline).
Примеры тегов:
<section>, <article>, <aside>, <nav>
Где можно использовать:
- Внутри элементов flow-контента
Что можно вложить внутрь:
- Flow-контент (например, заголовки, параграфы, списки и др.)
Нельзя:
- Вкладывать в phrasing-контент, например, внутрь <p>, <span>
Особенности:
- Если элемент sectioning-контента не содержит заголовка (<h1>–<h6>), то он считается безымянным разделом
- Рекомендуется использовать только там, где действительно есть смысловое деление
4. Heading content
Назначение: Элементы, которые задают заголовки разделов. Они определяют уровни иерархии в структуре документа.
Примеры тегов:
<h1>, <h2>, <h3>, <h4>, <h5>, <h6>, <hgroup>
Где можно использовать:
-
Внутри flow-контента
-
Обычно используются внутри sectioning-контента
Что можно вложить внутрь:
- Текст и phrasing-контент
Нельзя:
- Вкладывать другие блоки (<section>, <div>, и т.п.)
Особенности:
-
<hgroup> группирует несколько заголовков (например, заголовок и подзаголовок)
-
<h1>–<h6> определяют уровень важности, а не визуальное оформление
5. Phrasing content
Назначение: Контент, который участвует в потоке текста. Это inline-элементы, то есть те, что отображаются внутри строки. Они не создают новых блоков.
Примеры тегов:
<span>, <a>, <strong>, <em>, <abbr>, <code>, <label>, <img>, <input>, <select>, <textarea>, <small>, <sub>, <sup>, <time>, <br>
Где можно использовать:
-
Внутри других phrasing- или flow-элементов
-
Внутри заголовков, абзацев, ссылок, кнопок
Что можно вложить внутрь:
-
Другие phrasing-элементы
-
Текст, встроенные элементы
Нельзя:
-
Вложить блочные элементы (<div>, <p>, <section> и др.)
-
Нарушать контекст, например, <div><p><span><section>…</section></span></p></div> — ошибка
Особенности:
-
<a> и <span> часто используются как контейнеры phrasing-контента
-
Большинство формовых элементов (input, label, select) — тоже phrasing
6. Embedded content
Назначение: Вставка других видов контента: изображений, видео, аудио, SVG, canvas и др.
Примеры тегов:
<img>, <audio>, <video>, <canvas>, <iframe>, <embed>, <object>, <svg>, <math>
Где можно использовать:
- Внутри flow и phrasing-контента
Что можно вложить внутрь:
-
Некоторые (например, <video>, <audio>, <object>) могут содержать другие элементы
-
Остальные — пустые или содержат собственные API
Нельзя:
-
Использовать в metadata
-
Нарушать правила вложенности (например, <audio> в <p> — допустимо, но нужно следить за тем, чтобы не нарушить структуру phrasing-контента)
Особенности:
-
<iframe> может загружать другие HTML-страницы
-
<canvas> и <svg> позволяют рисовать графику
-
<object> и <embed> встраивают сторонние приложения
7. Interactive content
Назначение: Элементы, с которыми может взаимодействовать пользователь — клик, ввод, раскрытие.
Примеры тегов:
<a>, <button>, <details>, <input>, <label>, <select>, <textarea>, <summary>
Где можно использовать:
- Внутри flow и phrasing-контента
Что можно вложить внутрь:
-
Только phrasing-контент
-
Не разрешается вкладывать другие интерактивные элементы
Нельзя:
-
Вложить <button> внутрь <a>, или наоборот
-
Вложить интерактив в интерактив
Особенности:
-
<label> связывается с input
-
<details> можно раскрывать/сворачивать, <summary> — заголовок
Как определить допустимость вложенности
HTML-спецификация описывает вложения по двум направлениям:
-
Что элемент принимает (Content model) — какие категории контента допустимы внутри него.
-
К каким категориям относится сам элемент — определяет, в какие контейнеры он может быть вложен.
Пример: <a href=”#”> <button>Click</button> </a>
-
<a> принимает phrasing content
-
<button> — интерактивный элемент и тоже относится к phrasing
-
Но по правилам “interactive inside interactive” запрещено → ошибка