Самый понятный учебник веб-разработки полноценных веб-страниц
"Семантика HTML" подразумевает, что вся ваша HTML-разметка должна передавать основной смысл вашего контента, а не его внешний вид. Мы уже писали семантический HTML код, например, используя <strong> вместо <b>), но существует целый набор элементов, созданных с единственной целью - добавить больше смысла в общий макет веб-страницы. Они называются "элементы секционирования" и выглядят примерно так:
Использование этих элементов вместо элементов <div> - важный аспект современной веб-разработки, так как это облегчает поисковым системам, программам чтения с экрана и т.п. идентификацию различных частей вашего сайта. Это также помогает вам как разработчику поддерживать сайт организованным, что, в свою очередь, облегчает его обслуживание.
В этой главе мы вернемся к простому HTML - без блоковой модели, flexbox или схем позиционирования. Однако это не значит, что вы не можете применить все правила CSS из предыдущих глав к этим новым элементам. Считайте, что элементы секционирования - это <div>, только с определенным смыслом.
Нашим примером к этому уроку будет простой нестилизованный HTML-документ. Создайте новый проект Atom под названием semantic-html с новым файлом article.html. Добавьте в него следующее:
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'/>
<title>Semantic HTML</title>
</head>
<body>
<h1>Interneting Is Easy!</h1>
<ul>
<li><a href='#'>Home</li>
<li><a href='#'>About</li>
<li><a href='#'>Blog</li>
<li><a href='#'>Sign Up</li>
</ul>
</body>
</html>
Предполагается, что <h1> и <ul> - это баннер верхнего уровня для нашего сайта, а не основное содержимое веб-страницы. Нам никогда раньше не приходилось делать такое различие, но именно об этом и пойдет речь на этом уроке.
Каждый HTML-документ имеет "обводку", с помощью которой поисковые системы и программы чтения с экрана видят иерархию содержимого страницы. Обводку страницы формируют элементы заголовков секций <h1> - <h6>. Мы проверим это, добавив фиктивный блог-пост в article.html:
<h1>Semantic HTML</h1>
<p>By Troy McClure. Published January 3rd</p>
<p>This is an example web page explaining HTML5 semantic markup.</p>
<h2>The Document Outline</h2>
<p>HTML5 includes several “sectioning content” elements that
affect the document outline.</p>
<h3>Headers</h3>
<p>The <code><header></code> element is one such sectioning
element.</p>
<h3>Footers</h3>
<p>And so is the <code><footer></code> element.</p>
<h2>Inline Semantic HTML</h2>
<p>The <code><time></code> element is semantic, but it’s not
sectioning content.</p>
<p>This fake article was written by somebody at InternetingIsHard.com, which
is a pretty decent place to learn how to become a web developer.</p>
<p>© 2017 InternetingIsHard.com</p>
HTML5 Outliner - это удобный инструмент просмотра обводки документа на странице. Пройдите по ссылке и вставьте весь файл article.html в текстовое поле внизу. Вы должны увидеть обводку нашего примера, которая в данный момент напоминает структуру письменной работы, которую вы учились делать в школе (см. скриншот ниже).
Каждый элемент <h1> создает новую секцию в обводке документа, а все менее заметные заголовки, которые следуют за ним, считаются подразделами этого заголовка верхнего уровня. Например, секция Semantic HTML имеет две подсекции: The document outline [Обводка документа] и Inline Semantic HTML [Встроенный семантический HTML]. То же относится к элементам <h2>, <h3> и далее до <h6>.
Обратите внимание, что фактическое значение уровня заголовка не играет особой роли: важно то, больше или меньше он заголовка текущей секции. Например, измените заголовки <h3> на <h4> и снова запустите Outliner. Поскольку <h4> все равно меньше родительского <h2>, это никак не должно повлиять на обводку документа.
Как обводка документа связана с семантическим HTML? Заголовки - одни из самых семантических элементов веб-страницы. Они играют важную роль в том, как поисковые системы определяют, что является важным на вашей веб-странице. Кроме того, семантические элементы HTML, о которых мы сейчас расскажем, добавляют больше смысла, а иногда даже изменяют стандартное поведение обводки.
Элемент <article> обозначает независимую статью на веб-странице. В него следует помещать только тот контент, который можно извлечь из вашей страницы и распространить в совершенно другом контексте. Например, такое приложение, как Flipboard, должно иметь возможность взять элемент <article> с вашего сайта, отобразить его в своем приложении и сделать так, чтобы он был понятен читателям.
Мы можем использовать <article>, чтобы выделить основной контент страницы как самостоятельную единицу, например, так:
<article>
<h1>Semantic HTML</h1>
<p>By Troy McClure. Published January 3rd</p>
<p>This is an example web page explaining HTML5 semantic markup.</p>
<!-- ... -->
<p>This fake article was written by somebody at InternetingIsHard.com, which
is a pretty decent place to learn how to become a web developer.</p>
</article>
<p>© 2017 InternetingIsHard.com</p>
Обратите внимание, мы оставили уведомление об авторских правах за пределами элемента <article>, так как это футер для всего сайта, а не конкретно для нашей статьи. По сути, элементы <article> это мини-веб-страницы в HTML-документе. У них есть свои заголовки, футеры и обводка документа, полностью изолированные от остальной части сайта.
Для таких вещей, как блог-посты, газетные статьи или веб-страницы, посвященные одной теме, часто используется только один элемент <article>. Однако вполне допустимо иметь более одного <article> на странице. Хороший пример - страница с множеством блог-постов. Каждый из них может быть обернут в отдельный набор тегов <article> (вам не нужно добавлять это в страницу article.html нашего примера):
<article>
<h1>First Post</h1>
<p>Some content</p>
</article>
<article>
<h1>Second Post</h1>
<p>Some content</p>
<h1>Subscription</h1>
<p>Some details</p>
</article>
<article>
<h1>Last Post</h1>
<p>Final bit of content</p>
</article>
Это говорит всем, кто смотрит на нашу страницу, о том, что здесь есть три разные статьи, которые можно разместить в интернете*. Думайте об этом как о способе объединить несколько HTML-файлов в один документ, не запутав поисковые системы, браузеры и другие машины, которые пытаются разобрать наш контент.
Сравните это с кучей общих элементов <div> с произвольными именами классов, и вы начнете понимать, как семантический HTML упрощает навигацию по Сети.
* - "разместить в интернете". В оригинале: can be syndicated. У этого слова огромное множество переводов. Наиболее подходящие переводы для данного случая: "синдицировать; передавать информацию в агентство печати; публиковать сразу в нескольких газетах; покупать статьи для их одновременной публикации в различных изданиях."
Элемент <section> похож на <article>, только он не должен иметь смысла вне контекста документа. То есть приложение вроде Flipboard не будет пытаться вытащить все <section>'s из вашей страницы и представить их как независимые части контента.
Представьте <section> как явный способ определения секций в обводке документа. Зачем нам это нужно, вместо того чтобы позволить уровням заголовков сделать это за нас? Часто для верстки секций нужен контейнер, и тогда имеет смысл использовать более описательный элемент <section>, а не общий <div>.
Давайте выделим две секции в нашем файле article.html:
<section> <!-- Добавьте это -->
<h2>The Document Outline</h2>
<p>HTML5 includes several “sectioning content” elements that
affect the document outline.</p>
<h3>Headers</h3>
<p>The <code><header></code> element is one such sectioning
element.</p>
<h3>Footers</h3>
<p>And so is the <code><footer></code> element.</p>
</section> <!-- Добавьте это тоже-->
<section> <!-- Добавьте и это тоже -->
<h2>Inline Semantic HTML</h2>
<p>The <code><time></code> element is semantic, but it’s not
sectioning content.</p>
</section> <!-- Не забудьте добавить и это -->
Это позволяет сохранить обводку документа в неизменном виде и придать ей дополнительную смысловую структуру, а также сделать отличный зацеп для любых CSS-стилей, которые мы захотим применить (например, цвет фона для определенной секции).
Предыдущее изменение также имеет интересный побочный эффект для неявного поведения секций в наших заголовках. Посмотрите, что произойдет, если мы опустим второй <h2> на более низкий уровень заголовка:
<section>
<h6>Inline Semantic HTML</h6> <!-- Измените здесь уровень заголовка -->
<p>The <code><time></code> element is semantic, but it’s not
sectioning content.</p>
</section>
Строка <h6> находится ниже, чем предшествующая ей <h3>, поэтому можно ожидать, что она станет частью секции Footer. Но не тут-то было: обводка документа остается точно такой же, как и раньше.
Добавляя эти элементы <section>, мы говорим обводке документа, что она должна определяться структурой вложенности элементов <section>, а не уровнями заголовков. В основном это означает, что каждый <section> может иметь свой собственный набор заголовков <h1> - <h6>, не зависящих от остальной части страницы.
Однако не следует использовать элемент <section> для манипулирования обводкой документа таким образом, поскольку браузеры, программы чтения с экрана и некоторые поисковики неправильно интерпретируют влияние <section> на обводку документа. Вместо этого всегда определяйте обводку страницы через уровни заголовков, используя <section> только в качестве замены контейнеров <div>, когда это необходимо.
Также обратите внимание, что каждый элемент <section> должен содержать хотя бы один заголовок, иначе он добавит в обводку документа "секцию без названия". Для примера попробуем обновить article.html как показано ниже, а затем снова прогоним его через HTML5 Outliner:
<h2>Inline Semantic HTML</h2>
<section>
<!-- Это будет "Untitled Section" [Секция без названия] -->
<p>The <code><time> element is semantic, but it’s not
sectioning content.</p>
</section>
Это создает новую секцию, но поскольку с ней не связан заголовок, обводка документа не знает, как ее назвать. При использовании элементов <section> подобного следует избегать.
Согласно спецификации HTML5, <section> - это довольно общий элемент. Это, а также тот факт, что браузеры и программы чтения с экрана не могут правильно интерпретировать его роль в обводке документа, затрудняет понимание того, когда и как его использовать. Советуем использовать <section> скорее как описательную обертку <div> для неявно определенных секций вашей страницы. Не используйте его для самостоятельного контента (для этого есть <article>) или когда он нужен исключительно для верстки.
Элемент <nav> позволяет разметить различные навигационные секции вашего сайта. Это касается основной навигации сайта, ссылок на связанные страницы в боковой панели, таблиц с контентом и практически любых групп ссылок. Например, в элемент <nav> следует поместить навигационное меню всего сайта:
<h1>Interneting Is Easy!</h1>
<nav> <!-- Добавьте это -->
<ul>
<li><a href='#'>Home</a></li>
<li><a href='#'>About</a></li>
<li><a href='#'>Blog</a></li>
<li><a href='#'>Sign Up</a></li>
</ul>
</nav> <!-- И это добавьте! -->
Это отличная семантическая информация для поисковых систем. Она помогает им быстро определить структуру всего вашего сайта, облегчая поиск других страниц. Как мы увидим в разделе Элементы <aside>, в одну страницу можно включить несколько элементов <nav> при наличии разных наборов связанных ссылок.
<header> это новый элемент семантической разметки, который не следует путать с заголовками (элементы <h1>-<h6>). Он обозначает вводный контент для секции, статьи или всей веб-страницы. "Вводным контентом" может быть что угодно - от логотипа вашей компании до навигационных подсказок или информации об авторе.
Название/логотип и основную навигацию сайта лучше всего заключать в <header>, поэтому давайте добавим его в наш пример проекта:
<header>
<h1>Interneting Is Easy!</h1>
<nav>
<ul>
<li><a href='#'>Home</a></li>
<li><a href='#'>About</a></li>
<li><a href='#'>Blog</a></li>
<li><a href='#'>Sign Up</a></li>
</ul>
</nav>
</header>
Заголовки связаны только с ближайшим элементом секции - как правило, элементом <body>, <section> или <article>. Это означает, что вы можете использовать несколько элементов <header> для добавления вводного контента в разные части документа. Например, название, автор и дата публикации нашей <article> - вполне подходящий кандидат для другого <header>:
<article>
<header>
<h1>Semantic HTML</h1>
<p>By Troy McClure. Published January 3rd</p>
</header>
<p>This is an example web page explaining HTML5 semantic markup.</p>
<!-- ... -->
Без этого <header> поисковые системы и программы чтения с экрана не узнают, что первый <p> отделен от основного контента статьи. Как и <section>, он также служит удобным CSS-крючком, поскольку заголовок и информация об авторе записи в блоге часто оформляются иначе, чем остальная часть статьи. Повторимся, <header> можно рассматривать как более семантическую альтернативу контейнеру <div>.
Концептуально футеры - это то же самое, что и хидеры, за исключением того, что они обычно располагаются в конце статьи/сайта, а не в начале. Обычно они используются для уведомления об авторских правах, навигации по футеру и биографий авторов в конце записей блога.
Футеры ведут себя так же, как и хидеры, - они тоже связаны с ближайшим элементом секции. Поэтому мы можем использовать их для уведомления об copyright страницы и информации об авторе внутри <article>. Добавьте следующие два элемента футера на нашу страницу article.html:
<article>
<header>
<h1>Semantic HTML</h1>
<p>By Troy McClure. Published January 3rd</p>
</header>
<p>This is an example web page explaining HTML5 semantic markup.</p>
<!-- ... -->
<footer> <!-- Добавьте это -->
<p>This fake article was written by somebody at InternetingIsHard.com,
which is a pretty decent place to learn how to become a web developer. This
footer is only for the containing <code><article></code> element.</p>
</footer> <!-- Добавьте это -->
</article>
<footer> <!-- И это тоже -->
<p>© 2017 InternetingIsHard.com</p>
</footer> <!-- Не забудьте закрыть! -->
</body>
</html>
Элемент <footer> внутри <article> предназначен только для контента этой статьи, что вполне логично, поскольку он содержит биографию автора. Второй футер, в свою очередь, связан со всей страницей.
Хидеры и футеры - это способ добавить дополнительную информацию в статью, но иногда мы хотим удалить информацию из статьи. Например, спонсируемая статья в блоге может содержать рекламу компании-спонсора; однако мы, вероятно, не захотим делать ее частью текста статьи. Именно для этого предназначен элемент <aside> - "отступление".
Давайте добавим фейковое рекламное объявление в файл article.html, прямо под заголовком статьи:
<article>
<header>
<h1>Semantic HTML</h1>
<p>By Troy McClure. Published January 3rd</p>
</header>
<!-- Фейковое объявление [fake advertisement]! -->
<aside class='advert'>
<img src='some-advert-image.png'/>
</aside>
<p>This is an example web page explaining HTML5 semantic markup.</p>
Несмотря на то что изображение находится внутри элемента <article>, роботы понимают, что оно имеет лишь косвенное отношение к контенту статьи. Если она выглядит иначе, чем остальная часть статьи, скорее всего, это отступление. Помимо рекламы, <aside> также подходит для выделения определений, статистики или цитат.
Когда <aside> используется за пределами <article>, он ассоциируется со страницей в целом (так же, как <header> и <footer>). Это делает его хорошим выбором для разметки боковой панели всего сайта. Под закрывающим тегом </article>, перед вторым <footer> добавьте следующее:
<aside class='sidebar'>
<h2>Sidebar</h2>
<p>Some sidebar content</p>
<nav>
<h3>HTML & CSS Tutorial</h3>
<ul>
<li><a href='#'>Introduction</a></li>
<li><a href='#'>Basic Web Pages</a></li>
<li><a href='#'>etc...</a></li>
</ul>
</nav>
<nav>
<h3>JavaScript Tutorial</h3>
<ul>
<li><a href='#'>Introduction</a></li>
<li><a href='#'>Hello, JavaScript</a></li>
<li><a href='#'>etc...</a></li>
</ul>
</nav>
</aside>
Обратите внимание на атрибуты class в обоих фрагментах. Если бы на этом уроке мы фокусировались на CSS, мы могли бы стилизовать наши элементы <aside> точно так же, как и все <div>, с которыми мы работали на протяжении всего этого учебника. Что приводит нас к...
Используйте семантический HTML всегда, когда это возможно, поскольку он помогает машинам понять структуру вашего контента и дает вам стандартный словарь для организации веб-страниц. Однако иногда требуется элемент-контейнер, но не имеет смысла использовать ни один из только что рассмотренных семантических элементов HTML. Нет ничего плохого в том, чтобы использовать обычный <div> чисто для верстки.
Например, если мы хотим отцентрировать страницу с помощью знакомой техники auto-margin, нам придется поместить всю страницу в контейнер. Это полностью соотносится с идеей "внешнего вида", поэтому <div> будет наилучшим вариантом:
<body>
<div class='page'> <!-- Начало контейнера div -->
<header>
<h1>Interneting Is Easy!</h1>
<nav>
<ul>
<li><a href='#'>Home</a></li>
<li><a href='#'>About</a></li>
<li><a href='#'>Blog</a></li>
<li><a href='#'>Sign Up</a></li>
</ul>
</nav>
</header>
<!-- ... -->
<footer>
<p>© 2017 InternetingIsHard.com</p>
</footer>
</div> <!-- Конец контейнера div -->
</body>
</html>
Это особенно актуально для flexbox, поскольку для правильной группировки элементов flex требуется много <div>. Иногда для этих flex-элементов подходит <section> или <nav>, но довольно часто в flexbox-макетах встречаются элементы <div>.
Суть в том, что не стоит использовать семантические элементы только ради того, чтобы их использовать. Неуместное использование хуже, чем полное отсутствие, поэтому, если сомневаетесь, смело используйте <div>.
Для людей даты и время существуют в разных формах. Вы можете назвать 3 января 2017 года "1/3/2017", "3 января" или в зависимости от даты, даже "вчера". Парсинг такого неоднозначного естественного языка для машин затруднителен и чреват ошибками, поэтому на помощь приходит <time>.
Элемент <time> представляет либо время суток, либо календарную дату. Предоставление машиночитаемой даты позволяет браузерам автоматически привязывать ее к календарям пользователей и помогает поисковикам легко определять конкретные даты. Простой поиск в Google покажет вам эффект от включения элемента <time> на вашей странице:
Давайте сделаем ясную дату публикации нашей статьи, обернув ее в теги <time>:
<article>
<header>
<h1>Semantic HTML</h1>
<p>By Troy McClure. Published <time datetime='2017-1-3'>January
3rd</time></p>
</header>
<!-- ... -->
Машиночитаемая дата определяется атрибутом datetime. Формат даты легко запомнить: от самого большого периода времени к самому маленькому: год, месяц, день (дата). Обратите внимание, что даже если год не включен в читаемый человеком текст, это говорит поисковым системам, что наша статья была опубликована в 2017 году.
В datetime также можно включать время и часовые пояса. Если бы мы хотели добавить к дате публикации время 3:00 вечера по тихоокеанскому времени, мы бы использовали следующее:
<time datetime='2017-1-3 15:00-0800'>January 3rd</time>
Само время указывается в 24-часовом формате, а -0800 - это смещение часового пояса относительно GMT* (в данном случае -0800 означает PST - тихоокеанское стандартное время**).
* - GMT - Greenwich Mean Time - среднее время по Гринвичу.
* - PST - Pacific Standard Time - тихоокеанское стандартное
время.
Элемент <address> похож на <time> тем, что он не имеет отношения к общей структуре документа, а скорее украшает родительский элемент <article> или <body> некоторыми метаданными. Он определяет контактную информацию автора статьи или веб-страницы. <address> не следует использовать для обычных физических адресов.
Например, мы хотим добавить адрес электронной почты автора в футер нашей статьи:
<footer>
<p>This fake article was written by somebody at InternetingIsHard.com, which
is a pretty decent place to learn how to become a web developer. This footer
is only for the containing <code><article></code> element.</p>
<address>
Please contact <a href='mailto:[email protected]'>Troy
McClure</a> for questions about this article.
</address>
</footer>
По умолчанию он будет оформлен так же, как <em>, но это легко изменить простым CSS-правилом. Кстати вы заметили href-ссылку для электронной почты? Подробности на сайте Mozilla Developer Network.
Последними (но, конечно, не по значимости), являются элементы <figure> и <figcaption>. Первый это "рисунок", например, диаграмма, иллюстрация или даже фрагмент кода. А опциональная <figcaption> это подпись, связанная с родительским элементом <figure>.
Чаще всего они используются для добавления видимых описаний к элементам <img/> в статье, например, так:
<section>
<h2>The Document Outline</h2>
<p>HTML5 includes several “sectioning content” elements that
affect the document outline.</p>
<figure>
<img src='semantic-elements.png'
alt='Diagram showing <article>, <section>, and <nav> elements'/>
<figcaption>New HTML5 semantic elements</figcaption>
</figure>
<!-- ... -->
Атрибут alt тесно связан с элементом <figcaption>. Атрибут alt должен служить текстовой заменой изображения, а <figcaption> - это вспомогательное описание, отображаемое либо с изображением, либо с его текстовым эквивалентом.
Используя <figcaption> вышеуказанным образом можно смело опустить атрибут alt картинки без ущерба для SEO. В зависимости от того, с какими картинками вы работаете, может оказаться более удобным (и менее избыточным) иметь видимые <figcaption>, которые описывают их, в отличие от невидимых атрибутов alt.
И наконец, небольшое замечание по поводу устаревших браузеров. Вышеперечисленные семантические элементы HTML появились в HTML5. Все современные браузеры распознают их без дополнительной работы, но иногда в глобальных таблицах CSS можно увидеть что-то вроде:
section, article, aside, footer, header, nav {
display: block;
}
Это заставляет новые семантические элементы вести себя в старых браузерах как элементы <div> (являющимися блоковыми блоками а не строчными).
Определение графических стилей с помощью CSS - это то, как мы передаем структуру веб-страницы людям. Размечая ее с помощью <header>, <article>, <figure> и других элементов <section> HTML, мы можем передать эти визуальные стили и машинам.
Чтобы понять, почему это важно, представим себе машины, читающие наш контент. До появления семантического HTML разработчики использовали кучу элементов <div> с различными и несколько произвольными именами классов, определяющими структуру страницы. Например, все следующие элементы являются логическими именами для заголовка сайта:
<div class='main-menu'>
<div class='top-nav'>
<div class='top-banner'>
<div class='header'>
Раньше машины должны были понимать все вышеперечисленные <div> и многое другое. Новые семантические элементы HTML из этого урока - это как бы стандартизированные версии названий этих классов. Теперь они могут просто искать элемент <header>. Мы по-прежнему можем добавлять к нему любые имена классов для стилизации, но поисковики теперь имеют предсказуемый способ идентификации заголовков на всех HTML5-сайтах в Интернете.
Семантические элементы, описанные выше, для современных веб-сайтов являются оптимальными, но они едва ли исчерпывают все возможности, которые можнг придать веб-страницам. Вот только для начала:
Все эти аспекты относятся к области технического SEO, поэтому мы оставим их изучение на ваше усмотрение. На следующем уроке мы снова переключимся на изучение еще одного немаловажного компонента веб-сайтов (особенно электронной коммерции) - формами.