Pull to refresh

Избегаем распространенных ошибок в HTML5 разметке

Reading time8 min
Views120K
Original author: Richard Clark
HTML5 Уважаемые хабровчане, представляю вам вольный перевод статьи Avoiding common HTML5 mistakes. Здесь мы рассмотрим частые ошибки в HTML5 разметке с точки зрения семантики, и как их избежать.

Наблюдая за сайтами в галерее HTML5 сайтов и отвечая на вопросы пользователей, я видел множество сайтов с HTML5 разметкой. В этой статье я покажу некоторые ошибки и плохие практики разметки, которые я часто встречал, и объясню, как избежать их.

Не используйте тег <section> в качестве обёртки для оформления


Одна из наиболее общих проблем, замеченных мною, — банальная замена <div>'ов на структурные элементы HTML5, особенно на <section>'ы. Т.е. когда то, что в XHTML или HTML4 выглядит так:
<!-- Код в стиле HTML 4 -->
<div id="wrapper">
  <div id="header">  
    <h1>My super duper page</h1>
    <!-- Содержимое хедера -->
  </div>
  <div id="main">
    <!-- Контент страницы -->
  </div>
  <div id="secondary">
    <!-- Дополнительный контент -->
  </div>
  <div id="footer">
    <!-- Содержиме футера -->
  </div>
</div>
Переписывают так:
<!-- Не используйте этот код! Он неверен! -->
<section id="wrapper">
  <header>  
    <h1>My super duper page</h1>
    <!-- Содержимое хедера -->
  </header>
  <section id="main">
    <!-- Контент страницы -->
  </section>
  <section id="secondary">
    <!-- Дополнительный контент -->
  </section>
  <footer>
    <!-- Содержимое футера -->
  </footer>
</section>

Это просто неправильно: <section> не обёртка. Этот элемент означает семантический блок Вашего контента, использующийся для построения «структуры документа» (document outline), и должен содержать заголовок. Если Вам нужен элемент для обёртки, попробуйте обойтись <body> (Kroc Camen может предложить кое-что). Если это не решает проблему необходимости дополнительных обёрток, используйте старые добрые <div>'ы. С приходом HTML5 <div>'ы не умерли, и именно они отлично подходят в этом случае.

Принимая во внимание все вышесказанное, было бы хорошо разметить пример выше с использованием HTML5 так:
<body>
  <header>  
    <h1>My super duper page</h1>
    <!-- Содержимое хедера -->
  </header>
  <div role="main">
    <!-- Контент страницы -->
  </div>
  <aside role="complementary">
    <!-- Дополнительный контент -->
  </aside>
  <footer>
    <!-- Содержимое футера -->
  </footer>
</body>


Если Вы не уверены, какой элемент использовать, то я советую Вам воспользоваться нашей блок-схемой выбора элемента (прим. переводчика: см. в самом низу записи).

Используйте <header> и <hgroup> только при необходимости


Нет смысла писать код, если в этом нет необходимости, правда? Увы, но я часто наблюдаю, как <header> и <hgroup> там, где они не нужны. Вы можете почитать об элементах <header> и <hgroup> подробнее, я же коротко обозначу ключевые моменты:
  • Элемент <header> представляет группу вводных или навигационных средств и обычно содержит заголовок секции
  • Элемент <hgroup> группирует набор элементов <h1>-<h6>, представляя заголовок секции в случае, если он состоит из нескольких уровней (подзаголовки, альтернативные заголовки и т.д.)


Избыток элементов <header>

Я уверен, Вы прекрасно знаете, что элемент <header> можно использовать несколько раз в документе. Поэтому часто встречается такое:
<!-- Не используйте этот код! Здесь header не нужен! -->
<article>
  <header>  
    <h1>My best blog post</h1>
  </header>
  <!-- Содержимое статьи -->
</article>


Если Ваш <header> содержит только один заголовочный элемент, то он не нужен. В данном случае элемент <article> уже гарантирует, что заголовок будет включен в «структуру документа» (document outline), и раз <header> не содержит нескольких элементов (согласно определению), его можно безопасно удалить. Достаточно просто этого:
<article>  
  <h1>My best blog post</h1>
  <!-- Содержимое статьи -->
</article>


Неправильное использование <hgroup>

И снова о заголовках: я часто вижу некорректное использование элемента <hgroup>. Не следует использовать <hgroup> вместе с <header>, если:
  • Присутствует только один заголовок
  • <hgroup> хорош сам по себе (т.е., без <header>).

Первый случай:
<!-- Не используйте этот код! Здесь hgroup не нужен -->
<header>
  <hgroup>  
    <h1>My best blog post</h1>
  </hgroup>
  <p>by Rich Clark</p>
</header>


В этом случае просто уберите hgroup.
<header>
  <h1>My best blog post</h1>
  <p>by Rich Clark</p>
</header>


Второй случай — это еще один пример использования элемента без необходимости.
<!-- Не используйте этот код! Здесь header не нужен -->
<header>
  <hgroup>  
    <h1>My company</h1>
    <h2>Established 1893</h2>
  </hgroup>
</header>


Если единственный ребёнок <header>'а это <hgroup>, зачем нужен <header>? Если у Вас нет дополнительных элементов в <header>'е (т.е. сестринских по отношению к <hgroup>), просто уберите <header>.
<hgroup>
  <h1>My company</h1>
  <h2>Established 1893</h2>
</hgroup>


Подробнее об элементе <hgroup> можно почитать тут.

Не обрамляйте все ссылки в <nav>


В HTML5 было введено 30 новых элементов, чтобы дать нам возможность создавать структурированную и осмысленную разметку. Но не следует злоупотреблять новыми семантическими элементами. К сожалению, это как раз то, что происходит с <nav>. Спецификация описывает <nav> так:

Элемент nav представляет секцию страницы, связывающую её с другими страницами или частями текущей (секцию с навигационными ссылками).

Примечание: Не все группы ссылок следует помещать в элемент nav. Его следует использовать для основной навигации. Часто в футерах размещают небольшой список ссылок на различные страницы сайта (Главная, Помощь, соглашение об использовании, etc). В этом случае одного footer'а должно быть достаточно. Хотя ничто не мешает использовать nav, в этом нет необходимости.
WHATWG HTML spec

Ключевая фраза — «основная навигация». Можно долго спорить о том, что понимать под основной, но для меня это:
  • Первичная навигация
  • Поиск по сайту
  • Вторичная навигация (спорно)
  • Внутристраничная навигация (внутри длинной статьи, например)

Хотя в этом случае сложно судить, что есть правильно, а что — нет, я считаю, что не стоит заключать в <nav>:
  • Переключатели страниц
  • Социальные ссылки (хотя возможны исключения в случаях, когда социальные ссылки являются основной навигацией. Например, сайты вроде about.me или flavours.me)
  • Теги поста
  • Категории поста
  • Третичная навигация
  • Объемные футеры

Если Вы не уверены, обрамлять ли список ссылок в <nav>, задайте себе вопрос: «Это основная навигация?». Примите во внимание следующее:
  • “Не используйте <nav>, если Вы считаете, что <section> с заголовком <hx> тоже подойдёт” — Hixie в IRC
  • Возможно стоит добавить «Перейти к» для удобства?

Если ответ на эти вопросы — «Нет», это, видимо, не место для <nav>.

Общие ошибки в использовании элемента <figure>


Ах, <figure>. Разобраться с правильным использованием этого элемента, как и его собрата <figcaption>, непросто. Давайте взглянем на некоторые общие ошибки, касающиеся этого элемента.

Не каждое изображение <figure>

Ранее, я советовал не писать больше кода, чем необходимо. Здесь похожая ситуация. Я встречал сайты, где каждая картинка была обрамлена в <figure>. Не нужно использовать больше разметки только для того, чтобы использовать больше разметки. Вы просто создаете себе больше работы, но никак не улучшаете описание своего контента.

Спецификация описывает <figure> как «автономный контент, возможно, с заголовком и обычно являющийся самостоятельным элементом потока». Вот она, вся красота <figure> — элемент можно спокойно переместить из основного содержимого, например, в сайдбар.

Вышеупомянутая блок-схема выбора элемента поможет Вам справиться с <figure>.

Если изображение несет только презентационную нагрузку, и на него нигде в документе не ссылаются, это определенно не <figure>. Иначе, задайте себе вопрос: «Необходимо ли это изображение в текущем контексте для понимания?». Если нет, это, видимо, не <figure> (возможно, <aside>). Если да, спросите себя, «Могу ли я переместить это в приложение?». Если ответ на оба вопроса Да, то, возможно, <figure> подойдёт.

Ваш логотип — не <figure>

Тоже самое касается и логотипа. Часто я вижу такое применение:
<!-- Не используйте этот код! Он неверен! -->
<header>
  <h1>
    <figure>
      <img src="/img/mylogo.png" alt="My company" class="hide" />
    </figure>
    My company name
  </h1>
</header>
<!-- Не используйте этот код! Он неверен! -->
<header>  
  <figure>
    <img src="/img/mylogo.png" alt="My company" />
  </figure>
</header>

Тут нечего добавить. Это просто неверно. Можно долго спорить о том, должен ли логотип быть в <h1>, но мы сейчас не об этом. Настоящая ошибка — злоупотребление элементом <figure>. <figure> следует использовать только когда Вы ссылаетесь на него в документе. Вряд ли Вы где-нибудь будете ссылаться на свой логотип. Достаточно этого:
<header>
  <h1>My company name</h1>
  <!-- Еще что-нибудь -->
</header>


<figure> может быть не только изображением

Другой частый случай недопонимания элемента <figure> заключается в предположении, что его можно применять только для картинок. Но это не так. В <figure> может быть заключено видео, аудио, графики (в SVG, например), цитата, таблица, блок кода, стихотворение или любая комбинация перечисленного. Не ограничивайте себя в использовании <figure> одними картинками. Наша задача как приверженцев веб-стандартов — описать контент нашей разметки.

Не так давно я писал об элементе <figure> подробнее. Советую почитать, если Вы хотите разобраться получше или освежить воспоминания.

Не используйте ненужный атрибут type


Это, возможно, наиболее общая проблема, встречаемая в HTML5 галерее. Хотя это и не ошибка, я считаю, что лучше избегать этого.

В HTML5 нет необходимости указывать атрибут type для элементов <script> и <style>. Хотя от них может быть непросто избавиться, если они автоматически добавляются Вашей CMS, нет смысла включать их в код, если Вы пишете его самостоятельно или можете управлять шаблонами. Т.к. все браузеры по-умолчанию считают, что все скрипты написаны на JavaScript, а стили — это CSS, такая разметка становится избыточной:
<!-- Не используйте этот код! Его разметка перегружена! -->
<link type="text/css" rel="stylesheet" href="css/styles.css" />
<script type="text/javascript" src="js/scripts"></script>

Вместо этого Вы можете просто написать:
<link rel="stylesheet" href="css/styles.css" />
<script src="js/scripts"></script>


Помимо прочего, Вы также можете сократить количество кода, расходующегося на указание кодировки. Глава Марка Пилгрима о семантике в книге Dive into HTML5 описывает все такие практики.

Некорректное использование атрибутов форм


Вы, должно быть, уже в курсе, что в HTML5 введено множество новых атрибутов форм. Мы рассмотрим их в ближайшее время, сейчас же я коротко расскажу, как делать не стоит.

Логические атрибуты

Существуют логические атрибуты также и для мультимедиа элементов и некоторых других. Описываемые мною правила применимы и для них.

Некоторые из новых атрибутов форм являются логическими, т.е. их наличие в разметке определяет поведение элементов. В том числе это:
  • autofocus
  • autocomplete
  • required


Я редко встречаю их, но в случае с required я видел такое:
<!-- Не используйте этот код! Он неверен! -->
<input type="email" name="email" required="true" />
<!-- Еще один плохой пример -->
<input type="email" name="email" required="1" />


В конечном счете, это ничем плохим не грозит. Клиентский HTML парсер встретит атрибут required в разметке и применит соответствующие правила. Но что если сделать по-другому и написать required=«false»?
<!-- Не используйте этот код! Он неверен! -->
<input type="email" name="email" required="false" />

Парсер по-прежнему увидит атрибут required и применит соответствующее поведение, несмотря на то, что Вы указали ему не делать этого. Очевидно, это не то, чего Вы хотели.

Логическое значение возможно применить тремя способами: (Второе и третье характерны для XHTML)
  • required
  • required=""
  • required=«required=»


Применительно к нашему примеру выше, мы могли бы написать так (в HTML):
<input type="email" name="email" required />
Tags:
Hubs:
+119
Comments92

Articles