Перейти к основному содержимому
    Назад к блогу
    РазработкаОпубликовано 9 октября 2026 г.

    Семантический HTML и альтернативный текст: фундамент доступного сайта

    Почему кнопка должна быть button, как размечать ориентиры и заголовки и как писать alt для фото, иконок и графиков — с примерами кода

    Семантический HTML и альтернативный текст: фундамент доступного сайта

    Часть 2 из 8 серии «Доступный веб на практике». Предыдущая часть: Доступность сайта: для кого она на самом деле и с чего начать.

    Большая часть доступности достаётся бесплатно — если использовать правильные HTML-элементы. В этой части: кнопки и ссылки, ориентиры и заголовки, а также альтернативный текст для изображений, SVG-иконок и видео.

    Семантический HTML — фундамент всего

    Правильный HTML-элемент бесплатно даёт роль, имя, состояние, клавиатурную поддержку и поведение, которое пользователи вспомогательных технологий ожидают. Самая частая ошибка — пытаться воссоздать это вручную.

    Кнопка — это <button>

    <!-- ❌ Плохо: div притворяется кнопкой -->
    <div class="btn" onclick="save()">Сохранить</div>
    
    <!-- ✅ Хорошо -->
    <button type="button" class="btn" onclick="save()">Сохранить</button>
    

    У <div> из первого примера нет роли (скринридер прочитает просто текст), он не попадает в порядок табуляции и не реагирует на Enter и Space. Чтобы «починить» его, понадобится вот это:

    <!-- Так тоже можно, но зачем? -->
    <div role="button" tabindex="0" class="btn"
         onclick="save()"
         onkeydown="if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); save(); }">
      Сохранить
    </div>
    

    И это всё ещё хуже настоящей кнопки: нет поддержки disabled, отправки формы, правильного поведения Space (настоящая кнопка срабатывает на отпускание). Вывод простой: используйте <button>. Стили сбрасываются одной строкой all: unset или парой свойств.

    Ссылка или кнопка?

    Правило: ссылка ведёт куда-то, кнопка что-то делает.

    • Переход на другую страницу или к якорю — <a href="...">.
    • Открыть меню, отправить форму, переключить тему, удалить запись — <button>.
    <!-- ❌ Ссылка, которая ничего не открывает -->
    <a href="#" onclick="openMenu()">Меню</a>
    
    <!-- ✅ -->
    <button type="button" aria-expanded="false" aria-controls="main-menu">Меню</button>
    

    Пользователи скринридеров ожидают от ссылок и кнопок разного поведения, а у ссылки без href вообще нет роли и фокуса.

    Структура страницы: ориентиры

    HTML5-элементы секционирования автоматически становятся ориентирами (landmarks), по которым пользователь скринридера прыгает одной клавишей:

    <body>
      <a class="skip-link" href="#main">Перейти к содержимому</a>
    
      <header>                     <!-- banner -->
        <a href="/"><img src="logo.svg" alt="Agama Labs — на главную"></a>
        <nav aria-label="Основная"> <!-- navigation -->
          <ul>
            <li><a href="/services" aria-current="page">Услуги</a></li>
            <li><a href="/portfolio">Портфолио</a></li>
            <li><a href="/contact">Контакты</a></li>
          </ul>
        </nav>
      </header>
    
      <main id="main">             <!-- main -->
        <h1>Услуги</h1>
        ...
      </main>
    
      <aside aria-labelledby="related-title"> <!-- complementary -->
        <h2 id="related-title">Похожие статьи</h2>
        ...
      </aside>
    
      <footer>                     <!-- contentinfo -->
        ...
      </footer>
    </body>
    

    Несколько деталей:

    • <main> — один на страницу.
    • Если на странице несколько <nav>, подпишите их (aria-label="Основная", aria-label="Хлебные крошки"), иначе пользователь услышит «навигация, навигация».
    • aria-current="page" сообщает, на какой странице пользователь находится. Стилизовать текущий пункт удобно по этому же атрибуту: nav a[aria-current="page"] { ... }.

    Заголовки

    Заголовки — главный способ навигации. По опросу WebAIM среди пользователей скринридеров, большинство ищет информацию на странице именно по заголовкам (WebAIM Screen Reader Survey).

    • Уровни отражают структуру, а не размер шрифта. Нужен мелкий заголовок — делайте <h2> и уменьшайте его в CSS.
    • Не пропускайте уровни: после <h2> идёт <h3>, а не <h4>.
    • Обычно один <h1> на страницу — название страницы.
    • Не делайте заголовком текст, который просто должен быть жирным.

    Проверить структуру можно расширением вроде HeadingsMap или в панели скринридера.

    Списки, таблицы и прочее

    • Набор однородных элементов (пункты меню, карточки, шаги) — <ul>/<ol>. Скринридер скажет «список, 5 элементов», и человек сразу поймёт объём.
    • Табличные данные — <table> с <th scope="col"> / <th scope="row"> и <caption>. Таблицы для вёрстки не используйте.
    • Язык документа — <html lang="ru">. Без него скринридер прочитает русский текст английским синтезатором. Фрагменты на другом языке размечайте: <span lang="en">accessibility</span>.
    • Заголовок вкладки <title> уникален для каждой страницы: «Услуги — Agama Labs», а не одинаковое «Agama Labs» везде.

    Изображения, иконки и альтернативный текст

    Отсутствие alt — вторая по частоте ошибка в интернете. Но и «добавить хоть какой-то alt» — не решение.

    Как выбрать alt

    Задайте себе вопрос: что потеряет человек, если не увидит это изображение?

    Тип изображения Что писать в alt
    Информативное (фото товара, схема) Суть того, что изображено, в контексте страницы
    Функциональное (картинка внутри ссылки или кнопки) Куда ведёт или что делает, а не что нарисовано
    Декоративное (фоновый узор, «настроенческое» фото) Пустой alt=""
    Сложное (график, инфографика) Краткий alt + подробное описание рядом в тексте
    Изображение текста Тот же текст
    <!-- Информативное -->
    <img src="dashboard.png"
         alt="Панель заказов: таблица с номером, статусом и суммой каждого заказа">
    
    <!-- Функциональное: логотип-ссылка -->
    <a href="/"><img src="logo.svg" alt="Agama Labs — на главную"></a>
    
    <!-- Декоративное: пустой alt, а не отсутствующий -->
    <img src="wave.svg" alt="">
    
    <!-- Сложное: краткий alt + описание -->
    <figure>
      <img src="sales-2026.png" alt="График продаж за 2026 год, подробности ниже">
      <figcaption>
        Продажи росли с января по июнь с 120 до 340 заказов в месяц,
        летом снизились до 260, в сентябре вернулись к 330.
      </figcaption>
    </figure>
    

    Важная разница: пустой alt="" и отсутствующий alt — не одно и то же. Пустой говорит «это декорация, пропусти». Отсутствующий заставляет скринридер прочитать имя файла: «IMG underscore 4021 точка jpg».

    Не начинайте alt со слов «изображение…» или «картинка…» — скринридер и так сообщит роль.

    SVG-иконки

    <!-- Декоративная иконка рядом с текстом: скрываем -->
    <button type="button">
      <svg aria-hidden="true" focusable="false" width="16" height="16">
        <use href="#icon-trash"></use>
      </svg>
      Удалить
    </button>
    
    <!-- Кнопка только с иконкой: имя обязательно -->
    <button type="button" aria-label="Удалить заказ №1042">
      <svg aria-hidden="true" focusable="false" width="16" height="16">
        <use href="#icon-trash"></use>
      </svg>
    </button>
    
    <!-- Самостоятельная информативная SVG -->
    <svg role="img" aria-labelledby="chart-title" viewBox="0 0 200 100">
      <title id="chart-title">Конверсия выросла с 2% до 5%</title>
      ...
    </svg>
    

    Кнопка с одной иконкой без имени — это та самая «пустая кнопка» из статистики WebAIM (30,6% страниц). Скринридер скажет просто «кнопка».

    Альтернатива aria-label — визуально скрытый текст. Он лучше переводится автоматическими переводчиками и надёжнее для голосового управления:

    /* Скрыть визуально, но оставить для скринридеров */
    .visually-hidden {
      clip-path: inset(50%);
      height: 1px;
      width: 1px;
      overflow: hidden;
      position: absolute;
      white-space: nowrap;
    }
    
    <button type="button">
      <svg aria-hidden="true" focusable="false">...</svg>
      <span class="visually-hidden">Удалить заказ №1042</span>
    </button>
    

    Не используйте display: none или visibility: hidden для такого текста — они скрывают его и от скринридеров.

    Видео и аудио

    • У видео с речью — субтитры (<track kind="captions">). Автоматические субтитры проверяйте вручную.
    • У аудио (подкаст) — текстовая расшифровка.
    • Если важная информация передаётся только картинкой в видео (например, на экране показывают телефон, но не произносят его), нужна аудиодескрипция или текстовое описание.
    • Никакого автовоспроизведения со звуком.
    <video controls>
      <source src="demo.mp4" type="video/mp4">
      <track kind="captions" src="demo.ru.vtt" srclang="ru" label="Русский" default>
    </video>
    

    Серия «Доступный веб на практике»

    1. Доступность сайта: для кого она на самом деле и с чего начать
    2. Семантический HTML и альтернативный текст: фундамент доступного сайта — вы здесь
    3. Доступные формы: подписи, подсказки, ошибки и автозаполнение
    4. Клавиатура и фокус: как сделать сайт, которым можно пользоваться без мыши
    5. Контраст, анимация и размер кнопок: визуальная доступность сайта
    6. ARIA и динамический контент: когда атрибуты помогают, а когда вредят
    7. Доступность в React: id, фокус при смене маршрута и объявления
    8. Как тестировать доступность: автоматика, ручная проверка и чеклист

    Следующая часть: Доступные формы: подписи, подсказки, ошибки и автозаполнение

    Agama Labs — разработка сайтов и веб-приложений. Если хотите проверить доступность своего сайта, напишите нам: hello@agamalabs.com

    Контакты

    Давайте обсудим ваш проект

    Оставьте заявку, и мы свяжемся с вами в течение 2 часов для бесплатной консультации. Расскажите о вашей идее — поможем найти оптимальное решение.

    Время работы

    Пн–Пт: 08:00 – 17:00 (PST)
    Сб–Вс: Выходной

    Оставить заявку

    Заполните форму, и мы перезвоним вам

    Нажимая кнопку, вы соглашаетесь с политикой конфиденциальности

    Мы ценим вашу конфиденциальность

    Мы используем аналитические cookies, в том числе сторонних сервисов, чтобы понимать, как используется сайт, и улучшать его