Оглавление HTML5 документа

Механизм построения оглавления (outline) страницы базируется на тегах, используемых при разметке документа. Например, главная страница моего блога может иметь такое оглавление:

  1. Свежие заметки :: Хранитель заметок
    1. Свежие заметки
      1. Убираем неоднородности на повторяющейся текстуре
      2. Deferred Object
      3. Возвращаясь к проверке типа данных
      4. Тень у полей ввода в мобильном Safari
        1. Очень простое решение
      5. Таблица без таблицы или display: table-cell для всех браузеров
    2. Навигация по сайту
      1. Облако тегов
      2. Категории
      3. Ссылки
    3. Архив заметок по месяцам

Только два типа тегов влияют на оглавление страницы: заголовки (h1-h6 и hgroup) и структурные теги (section, article, aside и nav).

Влияние заголовков на построение оглавления

<div>
    <h1>Свежие заметки :: Хранитель заметок</h1>
    <!-- начинаем новый подраздел -->
    <h2>Свежие заметки</h2>
    <!-- начинается статья -->
    <h3>Убираем неоднородности на повторяющейся текстуре</h3>
    <!-- статья про неоднородности и как их убрать -->
    <p>Повторяющиеся текстуры бумаги или ткани могут быть с
        разными неоднородностями по площади.</p>
    ...
    <!-- статья закончилась и начинается новая -->
    <h3>Deferred Object</h3>
    <!-- статья про отложенные объекты -->
    <p>Термин «отложенный объект» тесно связан с событийной
        моделью создания компонент и модулей приложения.</p>
    ...
    <h3>Возвращаясь к проверке типа данных</h3>
    ...
    <h3>Тень у полей ввода в мобильном Safari</h3>
    ...
    <h4>Очень простое решение</h4>
    ...
    <h3>Таблица без таблицы или display: table-cell
        для всех браузеров</h3>
    ...
    <!-- раздел свежих заметок закончился и начинается новый раздел -->
    <h2>Навигация по сайту</h2>
    <h3>Облако тегов</h3>
    <ul>
        <li class="rank-9">jquery</li>
        <li class="rank-6">ui</li>
        <li class="rank-4">utility</li>
        <li class="rank-4">hint</li>
        <li class="rank-4">css</li>
    </ul>
    <h3>Категории</h3>
    <ul>
        <li>Вёрстка</li>
        <li>JavaScript</li>
        <li>Apple</li>
        <li>Разное</li>
    </ul>
    <h3>Ссылки</h3>
    ...
    <h2>Архив заметок по месяцам</h2>
    ...
</div>

Оглавление, построенное по заголовкам, подразумевает наличие неявных разделов. Каждый заголовок начинает неявный раздел документа. Заголовок меньшего уровня начинает подраздел внутри текущего и так далее. Неявный раздел документа заканчивается на заголовке того же или более высокого уровня.

Учет разделов при построении оглавления

Добавим в разметку страницы некоторые структурные элементы.

<div>
    <h1>Свежие заметки :: Хранитель заметок</h1>
    <section>
        <h2>Свежие заметки</h2>
        <article>
            <h3>Убираем неоднородности на повторяющейся текстуре</h3>
            <p>Повторяющиеся текстуры бумаги или ткани могут быть с
                разными неоднородностями по площади.</p>
            ...
        </article>
        <article>
            <h3>Deferred Object</h3>
            <p>Термин «отложенный объект» тесно связан с событийной
                моделью создания компонент и модулей приложения.</p>
            ...
        </article>
        <article>
            <h3>Возвращаясь к проверке типа данных</h3>
            ...
        </article>
        <article>
            <h3>Тень у полей ввода в мобильном Safari</h3>
            ...
            <h4>Очень простое решение</h4>
            ...
        </article>
        <article>
            <h3>Таблица без таблицы или display: table-cell
                для всех браузеров</h3>
            ...
        </article>
    </section>
    <nav>
        <h2>Навигация по сайту</h2>
        <section>
            <h3>Облако тегов</h3>
            <ul>
                <li class="rank-9">jquery</li>
                <li class="rank-6">ui</li>
                <li class="rank-4">utility</li>
                <li class="rank-4">hint</li>
                <li class="rank-4">css</li>
            </ul>
        </section>
        <section>
            <h3>Категории</h3>
            <ul>
                <li>Вёрстка</li>
                <li>JavaScript</li>
                <li>Apple</li>
                <li>Разное</li>
            </ul>
        </section>
        <section>
            <h3>Ссылки</h3>
            ...
        </section>
    </nav>
    <nav>
        <h2>Архив заметок по месяцам</h2>
        ...
    </nav>
</div>

Фактически структура оглавления ни сколько не поменялась. Но теперь разделы заданы явно с помощь тегов section, article, nav.

Одним из широко обсуждаемых нововведений HTML5 стало то, что в документе разрешено использовать несколько тегов h1. Из-за того, что деление на разделы происходит явно, внутри каждого раздела можно формировать свою структуру из заголовков.

В спецификации HTML5 указано:

Sections may contain headings of any rank, but authors are strongly encouraged to either use only h1 elements, or to use elements of the appropriate rank for the section’s nesting level.

Разделы могут содержать заголовки любого уровня. Но авторам настоятельно рекомендуется использовать только элементы h1 или элементы, соответствующие уровню вложенности раздела.

Лично я не стал бы использовать несколько элементов h1 до тех пор пока такой принцип разметки не получит поддержку в поисковых системах и читалках с экрана. Гораздо безопаснее структурировать документ, с использованием тегов явной разметки секций и заголовки такого же уровня, как если бы секции задавались неявно. С появлением полной поддержки вам не придется менять разметку страницы, так как она уже будет готова для обработки другим алгоритмом.

Смешанный подход

Неявные разделы могут появляется внутри явных разделов (но не наоборот).

<div>
    <h1>Свежие заметки :: Хранитель заметок</h1>
    <section>
        <h2>Свежие заметки</h2>
        <article>
            <h3>Тень у полей ввода в мобильном Safari</h3>
            ...
            <h4>Очень простое решение</h4>
            ...
        </article>
    </section>
</div>

Этот фрагмент документа, очевидно, выдаст следующую структуру:

  1. Свежие заметки :: Хранитель заметок
    1. Свежие заметки
      1. Тень у полей ввода в мобильном Safari
        1. Очень простое решение

Заголовок h4 образует неявный раздел внутри статьи, заданной явным образом тегом article.

Разделы без названия

Название явного раздела документа берется из ближайшего заголовка. Чаще всего без названия в оглавлении остаются разделы nav и aside. В спецификации нет жестких указаний на использование в них заголовков. Если все же такие разделы появляются по каким-либо причинам, то это не стоит считать плохой разметкой. Тем не менее, именование всех возможных разделов повышает понятность и доступность их содержимого.

Оставлять же без названия разделы section и article не стоит. Наличие такого раздела, например, может быть связано с не правильным выбором тега между div, section и article. Если для блока нельзя придумать заголовок, то его стоит просто разметить с помощью тега div.

Кстати говоря, элемент body так же получает название из ближайшего заголовка, а не из содержимого тега title, как можно предположить. И если такого заголовка не окажется, то документ останется без названия. Это серьезная проблема и таких ситуаций следует избегать, планируя разделы документа.

<body>
    <article>
        <h1>Blog post title</h1>
        <p>Blog post content</p>
    </article>
</body>

Такой документ останется без названия, так как появился явный раздел, размеченный тегом article. Чтобы решить эту проблему достаточно перед article поставить еще один тег h1 с аналогичным содержимым. Этот прием никак не повиляет на поисковую оптимизацию, так как заголовки будут одинаковыми (или почти одинаковыми).

hgroup

Элемент hgroup может содержать только заголовки и его назначение – это убрать все заголовки из оглавления кроме заголовка самого высокого уровня.

Инструменты и документация