Тег
Эта универсальность позволяет использовать теги
Грубые нарушения при использовании
Тег <div> приходит на вечеринку, где его встречает команда A11y
Ладно. Притормозим немного. Прежде чем дружно задирать нос перед применением тегов
Конечно, всегда, когда это возможно, нужно использовать семантические элементы. Но предлагаю проявить осторожность, создавая такую атмосферу, когда может показаться, что любой вариант использования
Прежде чем об этом поговорить — ненадолго вернёмся в прошлое и заглянем туда, откуда взялся тег
Элемент
В HTML 3.2 элементы
А именно,
Интересно тут то, что исходное определение тега
В стандарте HTML 4.01 определение
Но, без конкретной семантики, которую могут предложить эти элементы, нет реального способа программно определить то, как этот элемент можно или нужно использовать. Как минимум — определение этого невозможно так, чтобы его результат мог бы быть интерпретирован ассистивными технологиями. Особенно — когда в HTML5 появилась поддержка WAI-ARIA, а так же — элементы для группировки контента или для разбиения его на разделы, обладающие более специфической семантикой.
Знаете… нечто вроде «определения», но… речь идёт о
В HTML5 и в материалах «живого стандарта» HTML, который актуален в настоящий момент, описание элемента
Далее в стандарте идёт речь о следующем:
В MDN можно найти дальнейшие инструкции для разработчиков по использованию
В HTML AAM
Элемент
В результате получается, что правильное применение
К каким проблемам может привести оформление абзаца подобным образом? Об этом мы поговорим позже, а пока давайте посмотрим на несколько сценариев использования
Самый распространённый пример того, как не надо применять
Не вникая в особые подробности (можете почитать статью про
Но кто-то может пуститься во все тяжкие, создавая собственный элемент
Теперь, если говорить о структурных контейнерах содержимого, можно быстро определить, используется ли
Хотя этот пример и чрезвычайно упрощён, существуют сайты, созданные в наши дни, разметка которых напоминает вышеприведённый код.
Выше были описаны примеры неправильного использования
Разберём пару примеров совершенно допустимого применения
Для начала — пусть имеется набор абзацев или других элементов, содержащих текст на языке, который отличается от основного языка документа (веб-страницы). Тут
Здесь применение контейнера
Следующий пример, где в применении
Тут элементы
Тут вы можете подумать о том, что это — не такой уж и удачный пример, так как применение
В некоторых случаях эти замечания имеют смысл. Как уже говорилось, элементом
Помимо
Если пойти немного дальше, то окажется, что есть и другие элементы, вроде
Например — элемент
Но в HTML
Получается, что если
Если говорить об элементе
Причина, по которой элемент
Элементы с абстрактной ролью
Доступность страницы, на которой полно region-элементов, ухудшится. Ведь если знаком «Важно!» помечено всё вокруг, то окажется, что ничего важного, на самом деле, нет.
Возникает такое ощущение, что всё это очень похоже на
Если говорить о паре «правильных» примеров использования
То же самое касается и одного из первых моих примеров, который я обещал обсудить позже, где элемент
Возможно, первое, что пришло вам по этому поводу в голову, заключается в том, что такая конструкция не будет доступна тем, кто пользуется средствами для чтения с экрана. Исследуем эту идею.
Единственный HTML-элемент, который предназначен для оформления абзацев — это
Нам нужно беспокоиться о великом множестве проблем, которые могут возникнуть в сфере доступности контента. Надо ли разработчикам менять элементы
Не поймите меня неправильно: я не защищаю варианты использования
Пишите семантический HTML-код. Используйте его как стандарт. А ещё, может быть, не стоит беспокоиться слишком сильно, когда другие не используют семантический HTML, если то, что они создают, не приводит к проблемам с доступностью? Или, если призываете кого-то пользоваться семантическим HTML, предельно чётко описывайте проблему, которую это может решить. Семантические элементы HTML — это не только доступность контента. Они помогают другим инструментам, которые работают с HTML, их гораздо легче, чем бескрайнее море
Помните о том, что смысл элементов
Я, когда работал над черновиком этой статьи, пользовался презентацией Эрика Бэйли о пересечении производительности и доступности.
Статья с тех пор сильно изменилась, я не могу сообразить — куда мне добавить этот материал, не отклоняясь от основной цели. Но я, в любом случае, хочу привести тут ссылку на эту презентацию — для тех, кому интересна тема производительности и доступности. Делаю я так преимущественно из-за того, что не хочу рассказывать о том, о чём кто-то уже очень хорошо рассказал.
Всё закончилось хорошо. Думаю, всё закончилось хорошо.
Да, всё нормально.
Сталкивались ли вы с примерами неправильного использования
![](https://habrastorage.org/r/w1560/webt/ou/g5/kh/oug5kh6sjydt9llengsiebnp40w.png)
<div>
— это самый универсальный и широко используемый HTML-элемент. Сам по себе <div>
не представляет ничего, но он, в то же время, позволяет разработчикам превратить его почти во всё что угодно. Делается это посредством использования CSS (для стилизации), JavaScript (для функционала) и ARIA (для обеспечения доступности контента).Эта универсальность позволяет использовать теги
<div>
для множества самых разных целей, но, к сожалению, такая вседозволенность может легко привести к злоупотреблениям. Когда тегом <div>
пользуются недостаточно осмотрительно, в итоге может получиться <div>-суп, контент, лишённый семантического значения, интерактивные элементы, не отличающиеся доступностью, или некая комбинация этих нехороших явлений.Грубые нарушения при использовании
<div>
выявить сравнительно просто (подробнее об этом поговорим ниже). Но мы дошли до того, что кто-то может назвать «образцом недоступности контента» полностью правильное использование <div>
, или, как минимум, пример лёгкого отклонения от правильности. В таких ситуациях говорят о том, что «кому-то стоило бы вместо <div>
воспользоваться семантическим HTML-элементом».![](https://habrastorage.org/webt/pg/fl/7l/pgfl7lgs0drgl7binncjqy6mo8q.jpeg)
Ладно. Притормозим немного. Прежде чем дружно задирать нос перед применением тегов
<div>
— давайте вспомним о том, что контекст — это важно.Конечно, всегда, когда это возможно, нужно использовать семантические элементы. Но предлагаю проявить осторожность, создавая такую атмосферу, когда может показаться, что любой вариант использования
<div>
— это плохо… или — что замена некоего <div>
на «более семантический» элемент способна улучшить доступность некоего документа.Прежде чем об этом поговорить — ненадолго вернёмся в прошлое и заглянем туда, откуда взялся тег
<div>
.Семантическая (деградация) эволюция <div>
Элемент
<div>
появился в стандарте HTML 3.0. Он представлял собой «участок» контента. Вот его первоначальное описание: «Элемент DIV… представляет разные виды содержимого. Например — глава, раздел, аннотация, дополнение».В HTML 3.2 элементы
<div>
и <center>
были определены, в сущности, как один и тот же элемент.А именно,
<center>
рассматривался как «сокращение» для конструкции <div align=center>
. Он стал частью стандарта из-за того, что Netscape создала этот элемент до реализации стандартизированного элемента <div>
. В IT эту ситуацию сравнивают с тем, как коровы или овцы протаптывают дорожки по пастбищам. Одно из животных идёт по пути первым, а все остальные бездумно следуют за ним, не пытаясь найти более короткий или безопасный маршрут. В нашем случае <center>
— это путь в никуда.Интересно тут то, что исходное определение тега
<div>
можно рассматривать как очень раннюю идею, которая однажды, в более поздних версиях HTML, превратилась в идею разбиения контента на разделы. Не говорю, что в то время создатели стандарта стремились именно к этому, но очевидно, что тогда в HTML не хватало специфических элементов для распространённых контейнеров, нужных для разбиения контента на разделы или его группировки. Элемент <div>
или <center>
, как минимум, давал альтернативу тем, кто ранее размещал материалы в элементах <table>
.Элемент <div> в HTML 4.01
В стандарте HTML 4.01 определение
<div>
стало не таким детальным в плане того, что может представлять этот элемент. Там говорится об использовании <div>
в качестве универсального инструмента для структурирования контента. В HTML 4.01, кроме того, можно наблюдать исчезновение <center>
(Облом!) и появление элемента <span>
. Там элемент <div>
предлагается использовать для структурирования на уровне блоков контента, а <span>
— как универсальный контейнер для встроенного содержимого.Но, без конкретной семантики, которую могут предложить эти элементы, нет реального способа программно определить то, как этот элемент можно или нужно использовать. Как минимум — определение этого невозможно так, чтобы его результат мог бы быть интерпретирован ассистивными технологиями. Особенно — когда в HTML5 появилась поддержка WAI-ARIA, а так же — элементы для группировки контента или для разбиения его на разделы, обладающие более специфической семантикой.
Современное определение <div>
Знаете… нечто вроде «определения», но… речь идёт о
<div>
… Извиняюсь. Просто не могу это удалить.В HTML5 и в материалах «живого стандарта» HTML, который актуален в настоящий момент, описание элемента
<div>
стало таким:Элемент div совершенно не несёт в себе какого-то особого смысла. Он представляет свои дочерние элементы. Он может использоваться с атрибутами class, lang, title для обозначения семантики, общей для некоей последовательности элементов. Ещё его можно использовать в элементе dl, в качестве контейнера для групп элементов dt и dd.
Далее в стандарте идёт речь о следующем:
Авторам документов настоятельно рекомендуется рассматривать элемент div как элемент, к которому прибегают в самом крайнем случае, когда для решения некоей задачи не подходит ни один другой элемент. Использование более подходящих элементов вместо div ведёт к улучшению доступности документов для пользователей и к упрощению поддержки этих документов для их авторов.
В MDN можно найти дальнейшие инструкции для разработчиков по использованию
<div>
.В HTML AAM
<div>
назначена роль ARIA generic
. Определение этой роли в ARIA похоже на определение <div>
в HTML:Безымянный элемент-контейнер, который, сам по себе, не имеет никакого семантического значения.
Представление пустого места
Элемент
<div>
, ничего конкретного не представляющий, может быть чем угодно. Этот элемент, в сущности, является хаотичным нейтралом, он легко, по прихоти разработчика, может «перескакивать» между допустимыми и недопустимыми вариантами его использования.В результате получается, что правильное применение
<div>
может оказаться непростым для тех, кто ожидает наличия чётких указаний на то, что такое «хорошо» и «плохо» в разметке доступного контента. Взгляните, например, на следующий код:<div>Hi there, I'm a paragraph of content!</div>
К каким проблемам может привести оформление абзаца подобным образом? Об этом мы поговорим позже, а пока давайте посмотрим на несколько сценариев использования
<div>
, которые легче классифицировать как «плохие» и «хорошие».▍Очевидный пример неправильного использования <div>
Самый распространённый пример того, как не надо применять
<div>
— это когда с помощью этого элемента создают интерактивный контент вроде «ссылок» или «кнопок»:<div class=button onclick=foo()>
Click me!
</div>
Не вникая в особые подробности (можете почитать статью про
role=button
на MDN), могу сказать, что <div>
— это, по своей природе, не интерактивный элемент. Одна лишь стилизация не способна превратить <div>
, например, в кнопку. Даже добавление обработчика события click
не позволяет соблюсти все условия, необходимые для воссоздания доступной кнопки.Но кто-то может пуститься во все тяжкие, создавая собственный элемент
div-button
и оснащая его полноценными механизмами поддержки клавиатуры. Такой элемент может представлять себя в виде кнопки и в различных состояниях, характерных для кнопок (кнопка может быть, например, отключённой, нажатой, развёрнутой). Его создатель может, кроме того, поработать над тем, чтобы он хорошо функционировал бы в режиме высокой контрастности Windows. Если кто-то и правда решит всем этим заняться — пожелаем ему удачи. Но всё это потребует куда больше усилий, чем использование стандартного элемента <button>
. Правда, если сделать div-button
хорошо, то в этом не будет ничего совершенно несовместимого с жизнью. Правда?▍Элемент <div> и неправильное описание структуры документа
Теперь, если говорить о структурных контейнерах содержимого, можно быстро определить, используется ли
<div>
вместо более семантического элемента, взглянув на визуальное представление такого элемента. Ещё один способ заключается в анализе HTML-кода, названий классов или ID
, используемых для элементов (если только для всего этого применяются более или менее понятные имена):<body>
<div class=header>
...
</div>
<div id=main>
...
</div>
<div class=footer>
</div>
</body>
Хотя этот пример и чрезвычайно упрощён, существуют сайты, созданные в наши дни, разметка которых напоминает вышеприведённый код.
Выше были описаны примеры неправильного использования
<div>
, которые легко найти и исправить. Это может быть сделано путём замены элементов <div>
на другие, более подходящие элементы (вроде <main>
). Можно, при необходимости, задействовать ARIA для назначения элементам атрибутов role
, state
, aria-*
(например — <div role=main>
).▍Элементы <div>, с которыми всё хорошо
Разберём пару примеров совершенно допустимого применения
<div>
.Для начала — пусть имеется набор абзацев или других элементов, содержащих текст на языке, который отличается от основного языка документа (веб-страницы). Тут
<div>
можно использовать с атрибутом lang
, содержащим подходящий языковой тег. В этот <div>
можно включить весь контент на другом языке, это позволит указать на то, что этот язык использован в документе совершенно сознательно.<div lang=fr>
<h3><font color="#3AC1EF">▍...</font></h3>
<p>...</p>
<ul>
<li>...
<li>...
<li>...
...
</ul>
...
</div>
Здесь применение контейнера
<div>
с атрибутом lang
гораздо легче применения этого атрибута к каждому элементу, включённому в этот контейнер. Кроме того, если исходить из предположения о том, что этот контент представляет собой нечто особенное, используемое только на конкретной странице, окажется, что применение <div>
тут допустимо без всяких вопросов. Немного ниже мы ещё к этому вернёмся…Следующий пример, где в применении
<div>
нет никаких проблем, заключается в структурировании контента для целей стилизации:<main>
<div style="display: flex; ...">
<div style="flex: ...">
<h1>...</h1>
<!-- sub-heading / meta data could go here -->
</div>
<div style="flex: ...">
<!-- social follow links -->
</div>
</div>
<!-- other semantic elements / content go here -->
</main>
Тут элементы
<div>
применяются в роли контейнеров для элементов <h1>
и другого контента, имеющегося в начальной части статьи и предваряющего её основную часть. Здесь, для размещения контента, используется flex-макет (для упрощения примера здесь применены атрибуты style
).Тут вы можете подумать о том, что это — не такой уж и удачный пример, так как применение
<div>
для структурирования контента — это, вроде бы, не очень правильно. Может, тут стоило бы использовать больше доступных элементов?В некоторых случаях эти замечания имеют смысл. Как уже говорилось, элементом
<div>
часто пользуются неправильно, поэтому у того, кто взглянет на предыдущий пример, совершенно закономерно могут появиться подобные мысли. Но чтобы полноценно оценить эти примеры — нужно более полное понимание того, в каком контексте используется соответствующий код. Всё это, в конце концов, завязано на доступности контента.Универсальное применение любых других HTML-тегов
Помимо
<div>
есть и немало других, более семантических HTML-элементов, представляемых как универсальные (role=«generic»
). Среди них, например, такие, как <address>
, <kbd>
, <abbr>
, <body>
. Соответствующая роль назначается им неявным образом.Если пойти немного дальше, то окажется, что есть и другие элементы, вроде
<header>
, <footer>
и <section>
, которые, что часто встречается в разметке страниц, выглядят как generic-элементы. Причина этого кроется в том, что роли ARIA, управляющие доступностью элементов, имеют весьма специфические цели. У HTML-элементов, кроме того, имеется чётко определённая семантика, указывающая на предполагаемый способ использования их разработчиком. Но не у всех HTML-элементов семантика в точности совпадает с ролями ARIA, которые заданы им неявным образом.Например — элемент
<header>
, когда он находится внутри элемента <body>
, становится баннером — role=banner
. Это значит, что до тех пор, пока между <body>
и <header>
не будет элемента <main>
, элемента, предназначенного для разбиения контента на разделы, или корневого элемента раздела, элемент <header>
будет виден как banner
(абстрактная роль landmark
)Но в HTML
<header>
— это не всегда баннер. Этот тег полностью подходит, в том числе — и с семантической точки зрения, на роль потомка элемента <article>
или <section>
. Но в таком контексте теги <header>
не представляют собой контейнеров, содержащих, в основном, контент уровня всего сайта, а не конкретной страницы.Получается, что если
<header>
не вложен в <body>
, он становится универсальным элементом, таким же, как <div>
. Это относится, кроме того, и к элементу <footer>
.<body>
<header> I'm a banner! </header>
<main>
<header> I am NOT a banner! </header>
...
</main>
</body>
Если говорить об элементе
<section>
, то он, по умолчанию, тоже является универсальным. Он может быть представлен как элемент с ролью region
— если ему назначено доступное имя. Например:<!-- a generic section -->
<section>
<h2><font color="#3AC1EF">...</font></h2>
...
</section>
<!-- a 'region' landmark -->
<section aria-labelledby=h>
<h2 id=h>...</font></h2>
...
</section>
Причина, по которой элемент
<section>
ведёт себя именно так, заключается в крайнем распространении его неправильного использования, когда в этот раздел включают всё, что нужно и не нужно.Элементы с абстрактной ролью
landmark
предназначены для оформления особенно важных областей страниц. В частности, области с ролью region ориентированы на те ситуации, когда использование более специализированных landmark-элементов нецелесообразно.Доступность страницы, на которой полно region-элементов, ухудшится. Ведь если знаком «Важно!» помечено всё вокруг, то окажется, что ничего важного, на самом деле, нет.
Возникает такое ощущение, что всё это очень похоже на
<div>
. Правда?Суровость семантики
Если говорить о паре «правильных» примеров использования
<div>
, с уверенностью можно сказать, что в них можно было бы воспользоваться, соответственно, элементами <section>
и <header>
. В этом есть смысл с семантической точки зрения. Но роль этих элементов ничем не будет отличаться от роли уже используемых в примерах элементов <div>
.То же самое касается и одного из первых моих примеров, который я обещал обсудить позже, где элемент
<div>
играл роль контейнера абзаца:<div>Hi there, I'm a paragraph of content!</div>
Возможно, первое, что пришло вам по этому поводу в голову, заключается в том, что такая конструкция не будет доступна тем, кто пользуется средствами для чтения с экрана. Исследуем эту идею.
Единственный HTML-элемент, который предназначен для оформления абзацев — это
<p>
. Абзацы создаются неявным образом для каждого нового «блока» текста на странице. Поэтому, прежде чем разыграть карту «Используй семантический HTML и получишь в награду доступность», важно подумать о реальном воздействии на пользователя, о том, стоит ли сейчас разыгрывать эту карту. Лучше ли будет явным образом использовать <p>
? Да, лучше. Способствует ли это тому, что пользовательские стили смогут единообразно настраивать внешний вид абзацев? Да. Об этом ли обычно говорят, обсуждая использование <div>
вместо <p>
? Обычно — нет.Нам нужно беспокоиться о великом множестве проблем, которые могут возникнуть в сфере доступности контента. Надо ли разработчикам менять элементы
<div>
на другие, такие же универсальные, элементы, или на элементы, которые могут дать пользователям лишь небольшие улучшения, учитывая то, что имеется множество других, гораздо более срочных проблем, которые надо решить… Я не знаю. Полагаю, тут имеется множество сложностей, которые просто обходят молчанием.Не поймите меня неправильно: я не защищаю варианты использования
<div>
в случаях, в которых лучше использовать семантические элементы.Пишите семантический HTML-код. Используйте его как стандарт. А ещё, может быть, не стоит беспокоиться слишком сильно, когда другие не используют семантический HTML, если то, что они создают, не приводит к проблемам с доступностью? Или, если призываете кого-то пользоваться семантическим HTML, предельно чётко описывайте проблему, которую это может решить. Семантические элементы HTML — это не только доступность контента. Они помогают другим инструментам, которые работают с HTML, их гораздо легче, чем бескрайнее море
<div>
, понять разработчикам, модифицирующим чужую разметку.Помните о том, что смысл элементов
<div>
заключается в том, чтобы ничего не представлять. Они могут быть практически всем чем угодно… Главное — не делать из них «суп». Полагаю, что все мы можем сойтись хотя бы на том, что элементы <div>
для этого не предназначены.О «супе» из <div>
Я, когда работал над черновиком этой статьи, пользовался презентацией Эрика Бэйли о пересечении производительности и доступности.
Статья с тех пор сильно изменилась, я не могу сообразить — куда мне добавить этот материал, не отклоняясь от основной цели. Но я, в любом случае, хочу привести тут ссылку на эту презентацию — для тех, кому интересна тема производительности и доступности. Делаю я так преимущественно из-за того, что не хочу рассказывать о том, о чём кто-то уже очень хорошо рассказал.
Всё закончилось хорошо. Думаю, всё закончилось хорошо.
Да, всё нормально.
Сталкивались ли вы с примерами неправильного использования
<div>
в реальных проектах?![](https://habrastorage.org/webt/ou/g5/kh/oug5kh6sjydt9llengsiebnp40w.png)