Доступность длинной статьи: заголовки, ARIA-landmarks, клавиатура и фокус

Landmarks и заголовки в структуре длинной статьи

Длинная статья может выглядеть аккуратно, но при этом все равно оставаться неудобной для части пользователей. На экране видны крупные заголовки, боковая навигация и выделенные блоки, но программно документ оказывается почти плоским: разделы собраны из div, основные области страницы никак не обозначены, интерактивные элементы работают только мышью, а клавиатурный фокус теряется под фиксированной шапкой.

Доступность такого материала начинается не с набора ARIA-атрибутов. Сначала нужно сохранить смысловую структуру в HTML, затем обозначить крупные регионы страницы, обеспечить работу интерактивных элементов с клавиатуры и проверить, что пользователь всегда понимает, где находится фокус. Визуальная структура должна иметь программный эквивалент.

Саму смысловую модель длинного документа мы отдельно разбирали в материале об информационной архитектуре длинной страницы. Здесь задача начинается уровнем позже: структура уже существует, теперь её нужно сделать доступной разным способам восприятия и управления.

Доступность страницы начинается раньше ARIA

ARIA часто воспринимают как универсальный слой, который можно добавить поверх готовой разметки и тем самым «сделать страницу доступной».

Это опасное упрощение.

Если HTML уже имеет элемент с подходящей семантикой, обычно лучше использовать его:

  • <button> вместо кликабельного <div>;
  • <nav> для области навигации;
  • <main> для основного содержимого;
  • <aside> для дополнительной области;
  • <h1>–<h6> для заголовков;
  • обычную ссылку <a href="..."> для перехода.

W3C формулирует это как первое правило использования ARIA: если нативный HTML уже предоставляет необходимую семантику и поведение, не стоит воспроизводить их вручную через role и дополнительные атрибуты.

Например, вместо:

<div role="button" tabindex="0">Показать источники</div>

обычно разумнее начать с:

<button type="button">Показать источники</button>

Во втором варианте браузер уже знает, что перед ним интерактивная кнопка, и предоставляет ожидаемое поведение гораздо ближе к стандартному.

Заголовок должен существовать не только визуально

На длинной статье заголовки выполняют сразу несколько задач.

Визуально они помогают быстро просматривать материал. Семантически — описывают отношения между разделами. Assistive technologies могут использовать эту структуру для навигации по документу.

Поэтому строка, которая просто выглядит крупной, ещё не становится заголовком:

<div class="big-title">Результаты исследования</div>

Если это действительно начало самостоятельного раздела, разметка должна отражать эту функцию:

<h2>Результаты исследования</h2>

Это не означает, что любой визуальный акцент нужно превращать в heading. Сильный тезис внутри раздела может оставаться обычным абзацем, выделенным средствами CSS.

Эта граница уже важна для визуальной иерархии текстовой страницы: заголовок обозначает структурный уровень, а локальное выделение — важность мысли внутри него.

Уровни заголовков должны отражать отношения разделов

Для статьи обычно удобно иметь один основной заголовок страницы и затем строить подразделы по их реальной вложенности.

H1 — тема статьи
  H2 — основной раздел
    H3 — подраздел
    H3 — подраздел
  H2 — следующий основной раздел

Если подраздел относится к текущему H2, уровень H3 выражает эту связь.

Нежелательно использовать уровни только ради размера шрифта:

H2
  H4
H2
    H5

W3C рекомендует по возможности не перескакивать через уровни при движении внутрь структуры, поскольку это усложняет понимание иерархии.

Но здесь важно не превращать правило в механическую проверку HTML. Задача заголовков — прежде всего правильно описывать структуру документа, а их визуальный размер затем настраивается CSS.

Не нужно добавлять tabindex ко всем заголовкам и абзацам

Есть распространённая идея: если пользователь работает клавиатурой, значит через Tab он должен пройти вообще по каждому элементу страницы.

Для обычной статьи это обычно делает навигацию хуже.

Стандартная последовательность Tab предназначена прежде всего для интерактивных компонентов: ссылок, кнопок, полей форм и других элементов управления. Заголовки и обычные абзацы не нужно массово превращать в дополнительные остановки:

<h2 tabindex="0">Раздел</h2>
<p tabindex="0">Абзац...</p>
<p tabindex="0">Абзац...</p>

В длинном материале это способно создать десятки или сотни лишних шагов.

Screen reader и другие assistive technologies имеют собственные способы навигации по headings и структуре документа. Для клавиатурного Tab-пути важнее, чтобы логично работали именно интерактивные элементы.

Доступность не означает «сделать focusable всё подряд».

Landmarks описывают крупные области страницы

Заголовки структурируют содержание самой статьи. Landmarks решают другую задачу: обозначают крупные функциональные регионы всей страницы.

Типовая страница может содержать:

header
navigation
main
complementary content
footer

В HTML часть таких областей уже имеет встроенную landmark-семантику.

HTML Типичная функция
<main> Основное содержимое страницы
<nav> Навигационный регион
<aside> Дополнительное содержимое
верхнеуровневый <header> Вводная область сайта или страницы
верхнеуровневый <footer> Заключительная служебная область

Упрощённая структура может выглядеть так:

<a class="skip-link" href="#main-content">
  К основному содержанию
</a>

<header>
  ...
</header>

<nav aria-label="Основная навигация">
  ...
</nav>

<main id="main-content">
  <article>
    ...
  </article>

  <aside aria-label="Связанные материалы">
    ...
  </aside>
</main>

<footer>
  ...
</footer>

Assistive technologies могут использовать landmarks как карту верхнего уровня и быстро переходить между крупными областями.

Landmark не нужен каждому разделу статьи

После знакомства с ARIA легко перейти в другую крайность и превратить каждый смысловой блок в отдельный landmark:

region
region
region
region
region
region
...

Тогда карта страницы становится почти такой же шумной, как если бы landmarks вообще не было.

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

Например, десять H2 внутри одного <article> не требуют десяти role="region".

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

Если landmarks одного типа несколько, их нужно различать

На странице может существовать несколько областей <nav>:

  • главное меню сайта;
  • оглавление статьи;
  • навигация по предыдущим и следующим материалам.

Визуально они расположены в разных местах, поэтому различие очевидно.

Для программной структуры полезно дать им понятные доступные имена:

<nav aria-label="Основная навигация">
  ...
</nav>

<nav aria-label="Оглавление статьи">
  ...
</nav>

Тогда пользователь получает не два безымянных navigation-региона, а две области с разной функцией.

При этом саму механику оглавления, fragment-ссылок и переходов между разделами лучше не смешивать с landmarks. Она подробно разобрана отдельно в статье о навигации внутри длинного материала.

Skip-link позволяет не проходить меню на каждой странице заново

На сайте перед основным текстом часто расположены логотип, меню, поиск и другие повторяющиеся элементы.

Пользователь мыши может просто перевести взгляд ниже.

При последовательной клавиатурной навигации приходится проходить интерактивные элементы один за другим.

Для этого используется skip-link — ссылка в начале документа, позволяющая перейти сразу к основному содержимому:

<a href="#main-content" class="skip-link">
  К основному содержанию
</a>

<main id="main-content">
  ...
</main>

Такую ссылку можно постоянно показывать или делать видимой при получении клавиатурного фокуса.

Важно проверить не только сам переход viewport. После активации пользователь должен действительно оказаться в логичной точке основного документа и иметь возможность продолжить работу с клавиатуры.

Доступность касается функциональности, а не текста как такового

У длинной статьи может быть немного интерактивных компонентов, но именно они часто создают проблемы.

Например:

  • ссылки в тексте;
  • оглавление;
  • кнопка копирования кода;
  • кнопки поделиться;
  • раскрывающиеся блоки;
  • переключатели вкладок;
  • карусель;
  • поиск по странице;
  • видео- или аудиоконтролы;
  • форма комментария.

Если функция доступна мышью, нужно проверить, можно ли выполнить то же действие клавиатурным интерфейсом.

Это особенно важно для кастомных компонентов. Например, кликабельный <div> может реагировать на mouse click, но не иметь ожидаемого клавиатурного поведения.

Нативный HTML-контрол обычно уменьшает количество поведения, которое приходится воспроизводить вручную.

Порядок фокуса должен оставаться логичным

При обычной HTML-разметке последовательность клавиатурного фокуса во многом следует порядку focusable-компонентов в DOM.

Проблемы появляются, когда визуальная композиция и программный порядок расходятся.

Например, интерфейс визуально выглядит так:

Оглавление
↓
Статья
↓
Связанные материалы

а клавиатурный путь неожиданно прыгает:

Оглавление
↓
footer
↓
боковой баннер
↓
кнопка из середины статьи
↓
начало статьи

Тогда пользователю приходится восстанавливать устройство страницы по движению фокуса.

Особенно осторожно стоит относиться к положительным значениям tabindex:

tabindex="1"
tabindex="2"
tabindex="3"

Они позволяют вручную переопределять последовательность, но делают её хрупкой: после изменения страницы DOM и заданный вручную порядок легко начинают расходиться.

В большинстве обычных редакционных интерфейсов надёжнее сохранить логичный порядок элементов в самой разметке.

Фокус должен быть видим

Схема клавиатурной навигации и видимого фокуса на странице

Пользователь должен понимать, какой элемент сейчас активен.

Поэтому решение:

:focus {
  outline: none;
}

без равноценной замены создаёт проблему.

Можно оформить состояние более подходящим для дизайна способом, но оно должно оставаться заметным:

:focus-visible {
  outline: 3px solid currentColor;
  outline-offset: 3px;
}

Конкретное оформление зависит от интерфейса. Важен сам принцип: focus не должен существовать только внутри браузера как невидимое техническое состояние.

Sticky-header не должен закрывать элемент с фокусом

На длинных материалах часто закрепляют верхнюю навигацию.

Это удобно до тех пор, пока она не начинает закрывать ссылку или другой control, к которому пользователь пришёл клавиатурой.

WCAG 2.2 отдельно рассматривает сценарий, когда author-created content полностью перекрывает компонент, получивший клавиатурный focus.

Проверять нужно реальные состояния:

  • фокус на ссылке прямо под верхней границей viewport;
  • переход по оглавлению к разделу;
  • sticky-header после прокрутки;
  • фиксированные нижние панели;
  • плавающие рекламные или сервисные блоки.

Для якорных переходов могут понадобиться scroll-padding или scroll-margin, но конкретная реализация зависит от компоновки страницы.

Связь sticky-элементов с fragment-навигацией уже подробно разобрана в статье об оглавлении и якорных переходах. Здесь критерий шире: любой focusable-компонент должен оставаться доступным для работы.

Keyboard trap способен сделать недоступной всю оставшуюся статью

Ещё одна проблема возникает, когда focus попадает внутрь компонента, но пользователь не может выйти из него обычным клавиатурным способом.

Такое может произойти в:

  • самописном popup;
  • встроенном медиаплеере;
  • нестандартной карусели;
  • виджете комментариев;
  • кастомном диалоге;
  • интерактивной визуализации.

Для длинной статьи последствия особенно неприятны: пользователь доходит до элемента в середине материала и фактически теряет доступ ко всему, что находится ниже.

Поэтому при клавиатурном тесте важно не только войти в каждый интерактивный компонент, но и убедиться, что из него можно предсказуемо выйти.

ARIA не исправляет сломанную клавиатурную механику автоматически

Атрибут:

role="button"

сообщает дополнительную семантическую информацию.

Но он сам по себе не превращает произвольный div в полноценную HTML-кнопку со всем ожидаемым поведением.

Если используется кастомный компонент, разработчику всё равно приходится обеспечить:

  • возможность получить focus;
  • нужные клавиатурные действия;
  • понятное состояние;
  • правильное accessible name;
  • предсказуемое перемещение фокуса.

Именно поэтому принцип «native HTML first» полезен не как догма, а как способ не создавать вручную то, что платформа уже умеет.

равнение нативного HTML и дополнительной ARIA-разметки

Landmarks и headings отвечают на разные уровни карты

Полезно представить длинную страницу как две наложенные структуры.

Первая — карта всей страницы:

banner
navigation
main
complementary
contentinfo

Её помогают описывать landmarks.

Вторая — карта содержимого статьи:

H1
  H2
    H3
    H3
  H2
  H2

Её создают заголовки.

Одна структура не заменяет другую.

<main> говорит, где находится основное содержимое, но не объясняет устройство десяти разделов внутри статьи. А идеальная H2/H3-иерархия не сообщает, где заканчивается основное содержимое и начинается, например, глобальное меню или дополнительная колонка.

Визуальный порядок и программный порядок должны рассказывать одну историю

На desktop дизайнер может расположить дополнительный блок справа от основной статьи, хотя в DOM он находится после неё.

Это не обязательно ошибка.

Проблема появляется, если разница порядков меняет смысл.

Например, важное ограничение визуально показывается перед результатом, но в программной последовательности находится далеко после него. Пользователь screen reader сначала услышит вывод, а существенную оговорку получит значительно позже.

Для длинных доказательных материалов порядок часто является частью самого содержания.

Поэтому дизайн сетки не должен случайно переставлять смысловые зависимости только ради композиции.

Мобильная доступность и accessibility — пересекающиеся, но разные задачи

Адаптивная страница не становится автоматически доступной.

Можно идеально перестроить две колонки в одну и при этом оставить:

  • неправильную heading hierarchy;
  • невидимый focus;
  • кнопку, работающую только по click;
  • лишние landmarks;
  • keyboard trap.

И наоборот, часть accessibility-проблем существует даже на большом desktop-экране.

Мобильный сценарий поэтому остаётся отдельным слоем. Reflow, порядок блоков, ширина сложных компонентов и мобильная компоновка подробно разобраны в материале о мобильной версии длинной статьи.

Что стоит проверить вручную перед публикацией

Для первого прохода длинной статьи полезна простая последовательность.

  1. Посмотреть структуру headings. Понятно ли устройство материала без визуального оформления.
  2. Проверить основные landmarks. Есть ли один понятный основной регион и не размножены ли без необходимости одинаковые regions.
  3. Пройти страницу клавиатурой. Все ли интерактивные элементы доступны.
  4. Следить за порядком. Не прыгает ли focus между несвязанными областями.
  5. Проверить видимость focus. Понятно ли, какой control выбран.
  6. Проверить sticky-элементы. Не перекрывают ли они focused controls.
  7. Использовать skip-link. Действительно ли он позволяет перейти к основному материалу.
  8. Открыть интерактивные компоненты. Можно ли войти и выйти из них без мыши.
  9. Проверить страницу при узком viewport и увеличении. Не изменился ли смысловой порядок.

Такой ручной проход не заменяет полноценный accessibility-аудит, но хорошо обнаруживает ошибки, которые легко пропустить при обычной работе мышью.

Типичные ошибки длинной статьи

Ошибка Что происходит
Крупный текст вместо настоящего heading Визуальная структура не отражается программно
role="region" почти на каждом блоке Landmark-карта становится перегруженной
Несколько безымянных <nav> Пользователю сложнее понять функцию каждой области
tabindex="0" на каждом заголовке и абзаце Tab-путь заполняется неинтерактивным контентом
Положительные значения tabindex Порядок приходится поддерживать вручную и легко сломать
Удалён стандартный outline без замены Текущее положение клавиатурного фокуса становится незаметным
Sticky-header перекрывает focused element Пользователь не видит текущую точку взаимодействия
Кликабельный div вместо обычной кнопки Приходится вручную воспроизводить клавиатурное поведение
ARIA добавляется поверх неправильной структуры Атрибуты маскируют симптом, но не исправляют саму модель документа

Доступность не стоит превращать в SEO-трюк

Семантическая структура полезна не только assistive technologies. Она делает устройство документа более явным для программ, которые работают с HTML.

Но из этого не следует, что добавление role="main", ARIA-landmarks или определённого количества H2 само по себе повышает позиции страницы.

Это неправильная постановка задачи.

Доступность прежде всего отвечает на пользовательский вопрос:

может ли человек понять структуру страницы, найти нужное и воспользоваться её функциями независимо от того, работает ли он только мышью и визуальным интерфейсом?

Для длинной статьи это естественное продолжение общей UX-задачи. В более широком контексте она разобрана на странице о том, что происходит после клика и почему структура посадочной страницы влияет на пользовательский путь.

Итог

Доступная длинная статья не требует превращать каждый элемент в интерактивный и не требует размечать всю страницу ARIA-атрибутами.

Полезнее идти от структуры:

понятный HTML
↓
семантические headings
↓
крупные landmarks
↓
возможность пропустить повторяющиеся блоки
↓
клавиатурно доступные функции
↓
логичный порядок focus
↓
видимый и не перекрытый focus
↓
ручная проверка

Заголовки помогают понимать внутреннюю структуру текста. Landmarks дают карту крупных областей страницы. Keyboard navigation обеспечивает доступ к функциям. Focus показывает текущую точку взаимодействия.

Когда эти слои согласованы, длинный документ остаётся понятным не только визуально. Его устройство сохраняется и в самой разметке, и в способах навигации по ней.

Источники

Источники проверены 7 сентября 2026 года. Использованы официальные материалы W3C Web Accessibility Initiative.