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

    Контраст, анимация и размер кнопок: визуальная доступность сайта

    Требования к контрасту, информация не только цветом, режим высокой контрастности, prefers-reduced-motion, размер целей нажатия и масштабирование

    Контраст, анимация и размер кнопок: визуальная доступность сайта

    Часть 5 из 8 серии «Доступный веб на практике». Предыдущая часть: Клавиатура и фокус: как сделать сайт, которым можно пользоваться без мыши.

    Низкий контраст текста — самая частая проблема в интернете: она есть на 83,9% популярных сайтов. В этой части — всё визуальное: контраст и цвет, режимы отображения, анимация, размер целей нажатия и масштабирование.

    Цвет, контраст и режимы отображения

    Требования к контрасту

    Что Минимум (AA) Критерий
    Обычный текст 4,5 : 1 1.4.3
    Крупный текст (от 24 px, или от ≈18,7 px жирным) 3 : 1 1.4.3
    Компоненты интерфейса: границы полей, иконки, индикатор фокуса, состояния 3 : 1 1.4.11
    Значимые части графики (линии графика, сегменты диаграммы) 3 : 1 1.4.11

    Требование не распространяется на неактивные (disabled) элементы, логотипы и чисто декоративные элементы.

    Типичные проблемы:

    • светло-серый текст #999 на белом: всего ≈2,8 : 1;
    • placeholder и подсказки слишком бледные;
    • белый текст на ярком фирменном цвете;
    • текст поверх фотографии без подложки;
    • граница поля ввода #ddd на белом — поле «не видно» слабовидящему.

    Проверить контраст можно прямо в DevTools: в Chrome при выборе цвета в панели Styles показывается коэффициент контраста и отметки AA/AAA. Есть и отдельные инструменты — например, WebAIM Contrast Checker.

    Если цвета задаются в дизайн-системе, сразу заложите пары «фон — текст», проверенные на контраст, и запретите остальные комбинации.

    Не только цветом

    Критерий 1.4.1: цвет не должен быть единственным способом передать информацию. Около 8% мужчин имеют ту или иную форму нарушения цветовосприятия, а на солнце или на плохом мониторе цвета различает хуже любой.

    <!-- ❌ Ошибка обозначена только красной рамкой -->
    <input class="border-red">
    
    <!-- ✅ Цвет + иконка + текст -->
    <input aria-invalid="true" aria-describedby="err">
    <p id="err" class="error"><svg aria-hidden="true">...</svg> Укажите дату в будущем</p>
    

    То же со ссылками в тексте: если ссылка отличается от текста только цветом, контраст между ними должен быть не ниже 3 : 1 и нужен дополнительный признак при наведении и фокусе. Проще всего — оставить подчёркивание.

    /* Ссылки в тексте статьи — с подчёркиванием */
    .prose a {
      text-decoration: underline;
      text-underline-offset: 0.15em;
    }
    

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

    Режим высокой контрастности и тёмная тема

    В Windows есть режим контрастных тем (forced colors): браузер заменяет все цвета на системную палитру пользователя. Что в нём ломается:

    @media (forced-colors: active) {
      .icon {
        /* SVG с currentColor адаптируется сам; для масок — системный цвет */
        background-color: CanvasText;
      }
      .card {
        border: 1px solid CanvasText; /* вместо тени */
      }
    }
    

    Проверить можно в Chrome DevTools: Rendering → Emulate CSS media feature forced-colors.

    Тёмная тема через prefers-color-scheme тоже требует проверки контраста — пары цветов в ней свои.

    Движение и анимация

    Параллакс, масштабирование при прокрутке, большие сдвиги экрана вызывают у людей с вестибулярными нарушениями головокружение и тошноту. У людей с СДВГ бесконечная анимация мешает читать. В операционных системах есть настройка «Уменьшить движение», и браузер передаёт её через медиазапрос prefers-reduced-motion.

    /* Базовый подход: анимации включаем только тем, кто не просил их убрать */
    @media (prefers-reduced-motion: no-preference) {
      .hero {
        animation: slide-in 0.6s ease-out;
      }
      html {
        scroll-behavior: smooth;
      }
    }
    

    Или наоборот — глобальная страховка:

    @media (prefers-reduced-motion: reduce) {
      *,
      *::before,
      *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
      }
    }
    

    В JavaScript (например, для библиотек анимации):

    const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    
    element.animate(
      [{ transform: 'translateY(20px)', opacity: 0 }, { transform: 'none', opacity: 1 }],
      { duration: reduceMotion ? 0 : 400, easing: 'ease-out', fill: 'forwards' }
    );
    

    «Уменьшить движение» не значит «убрать всё»: плавное появление прозрачностью обычно допустимо, проблемы вызывают движение, масштаб и вращение.

    Ещё два правила:

    • Всё, что движется дольше 5 секунд (карусели, бегущие строки, фоновое видео), должно иметь кнопку паузы (критерий 2.2.2).
    • Ничего не мигает чаще трёх раз в секунду (2.3.1) — это может вызвать эпилептический приступ.

    Размер целей, жесты и масштабирование

    Размер цели нажатия

    Критерий 2.5.8 из WCAG 2.2 (уровень AA): интерактивная цель — не меньше 24×24 CSS-пикселя, либо вокруг маленькой цели должно быть достаточно свободного места, чтобы круг диаметром 24 px с центром на ней не пересекался с соседними целями. Для мобильных интерфейсов разумнее ориентироваться на рекомендации платформ: Apple — 44×44 pt, Material Design — 48×48 dp. Уровень AAA WCAG (2.5.5) — 44×44 CSS-пикселя.

    Увеличить зону нажатия можно, не меняя внешний вид:

    /* Иконка 16px, кликабельная область 44px */
    .icon-button {
      display: inline-grid;
      place-items: center;
      min-width: 44px;
      min-height: 44px;
      padding: 0;
    }
    
    /* Или расширить зону псевдоэлементом */
    .small-link {
      position: relative;
    }
    .small-link::after {
      content: "";
      position: absolute;
      inset: -10px;
    }
    

    Жесты и перетаскивание

    • Сложные жесты (щипок, свайп двумя пальцами, рисование траектории) должны иметь альтернативу одиночным нажатием (2.5.1). Карта масштабируется щипком — значит, нужны кнопки «+» и «−».
    • Перетаскивание (2.5.7, новое в 2.2): сортировка списка drag-and-drop, ползунки, загрузка файлов перетаскиванием — у всего этого должна быть альтернатива. Для сортировки — кнопки «Выше» / «Ниже» или меню «Переместить», для загрузки — обычная кнопка выбора файла.
    • Срабатывание по отпусканию (2.5.2): действие выполняется при отпускании (click, pointerup), а не при касании (pointerdown) — так человек может «передумать», уведя палец.

    Масштабирование и перекомпоновка

    • Не запрещайте масштабирование:

      <!-- ❌ -->
      <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
      
      <!-- ✅ -->
      <meta name="viewport" content="width=device-width, initial-scale=1">
      
    • Перекомпоновка (1.4.10): при ширине 320 CSS-пикселей (это масштаб 400% на экране 1280 px) контент должен читаться без горизонтальной прокрутки. Адаптивная вёрстка обычно решает это сама — проверьте, уменьшив окно или увеличив масштаб.

    • Размеры шрифта — в rem, а не в px, чтобы учитывалась настройка размера шрифта в браузере.

    • Межстрочные интервалы (1.4.12): вёрстка не должна ломаться, если пользователь увеличит межстрочный интервал до 1,5, межбуквенный — до 0,12 em, расстояние между словами — до 0,16 em. Главный враг — блоки с фиксированной высотой (height: 40px) вместо min-height.

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

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

    Следующая часть: ARIA и динамический контент: когда атрибуты помогают, а когда вредят

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

    Контакты

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

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

    Время работы

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

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

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

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

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

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