Уважаемые хабровчане, представляю вам вольный перевод статьи 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 представляет секцию страницы, связывающую её с другими страницами или частями текущей (секцию с навигационными ссылками).WHATWG HTML spec
Примечание: Не все группы ссылок следует помещать в элемент nav. Его следует использовать для основной навигации. Часто в футерах размещают небольшой список ссылок на различные страницы сайта (Главная, Помощь, соглашение об использовании, etc). В этом случае одного footer'а должно быть достаточно. Хотя ничто не мешает использовать nav, в этом нет необходимости.
Ключевая фраза — «основная навигация». Можно долго спорить о том, что понимать под основной, но для меня это:
- Первичная навигация
- Поиск по сайту
- Вторичная навигация (спорно)
- Внутристраничная навигация (внутри длинной статьи, например)
Хотя в этом случае сложно судить, что есть правильно, а что — нет, я считаю, что не стоит заключать в <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 />