Реализация режима повышенной доступности на сайте

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.
Разработка и обслуживание любых видов сайтов:
Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Реализация режима повышенной доступности на сайте
Средняя
~3-5 рабочих дней
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Реализация режима повышенной доступности на сайте

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

Компоненты режима доступности

Типичный набор опций:

  • Высококонтрастная тема (контраст 7:1+)
  • Увеличенный шрифт (+2–4px базовый размер)
  • Отключение анимации (prefers-reduced-motion)
  • Увеличенные зоны кликабельности
  • Более заметный индикатор фокуса
  • Упрощённый layout (одна колонка)

CSS-переменные как основа

/* Базовые переменные */
:root {
    --font-size-base: 16px;
    --color-text: #333333;
    --color-bg: #ffffff;
    --color-accent: #0056b3;
    --focus-outline: 2px solid #0056b3;
    --focus-outline-offset: 2px;
    --transition-duration: 300ms;
    --min-touch-target: 44px;
}

/* Режим высокого контраста */
[data-accessibility-mode~="high-contrast"] {
    --color-text:   #000000;
    --color-bg:     #ffffff;
    --color-accent: #0000CC;
    --focus-outline: 3px solid #000000;
    --focus-outline-offset: 4px;
}

/* Увеличенный шрифт */
[data-accessibility-mode~="large-text"] {
    --font-size-base: 20px;
}

/* Уменьшение анимации */
[data-accessibility-mode~="reduced-motion"],
@media (prefers-reduced-motion: reduce) {
    --transition-duration: 0ms;
    * {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
    }
}

/* Увеличенные цели касания */
[data-accessibility-mode~="large-targets"] {
    --min-touch-target: 56px;
    a, button, [role="button"] {
        min-height: var(--min-touch-target);
        min-width: var(--min-touch-target);
        display: inline-flex;
        align-items: center;
    }
}

React-компонент управления режимом

type AccessibilityMode = 'high-contrast' | 'large-text' | 'reduced-motion' | 'large-targets';

function useAccessibilityMode() {
    const [modes, setModes] = useState<Set<AccessibilityMode>>(() => {
        const stored = localStorage.getItem('a11y-modes');
        return stored ? new Set(JSON.parse(stored)) : new Set();
    });

    // Учитываем системные настройки
    useEffect(() => {
        const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
        if (mediaQuery.matches) {
            setModes(prev => new Set([...prev, 'reduced-motion']));
        }
    }, []);

    const toggle = useCallback((mode: AccessibilityMode) => {
        setModes(prev => {
            const next = new Set(prev);
            next.has(mode) ? next.delete(mode) : next.add(mode);
            localStorage.setItem('a11y-modes', JSON.stringify([...next]));
            return next;
        });
    }, []);

    // Применить к document.documentElement
    useEffect(() => {
        document.documentElement.dataset.accessibilityMode = [...modes].join(' ');
    }, [modes]);

    return { modes, toggle };
}

function AccessibilityPanel() {
    const { modes, toggle } = useAccessibilityMode();
    const [isOpen, setIsOpen] = useState(false);

    const options = [
        { id: 'high-contrast' as const,  label: 'Высокий контраст', icon: '◑' },
        { id: 'large-text' as const,     label: 'Увеличенный текст', icon: 'A+' },
        { id: 'reduced-motion' as const, label: 'Меньше анимации',   icon: '⏸' },
        { id: 'large-targets' as const,  label: 'Крупные кнопки',    icon: '⊞' },
    ];

    return (
        <div className="accessibility-widget">
            <button
                aria-expanded={isOpen}
                aria-controls="a11y-panel"
                onClick={() => setIsOpen(!isOpen)}
                aria-label="Настройки доступности"
            >
                ♿
            </button>

            {isOpen && (
                <div id="a11y-panel" role="group" aria-label="Настройки доступности">
                    {options.map(opt => (
                        <label key={opt.id} className="a11y-option">
                            <input
                                type="checkbox"
                                checked={modes.has(opt.id)}
                                onChange={() => toggle(opt.id)}
                            />
                            <span className="icon">{opt.icon}</span>
                            {opt.label}
                        </label>
                    ))}

                    <button
                        onClick={() => {
                            localStorage.removeItem('a11y-modes');
                            setModes(new Set());
                        }}
                    >
                        Сбросить настройки
                    </button>
                </div>
            )}
        </div>
    );
}

Системные медиа-запросы (без JS)

Часть настроек применяется автоматически из системных настроек:

/* Автоматически для пользователей, выбравших уменьшение анимации в ОС */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}

/* Системная высококонтрастная тема */
@media (prefers-contrast: more) {
    :root {
        --color-text: #000;
        --color-bg: #fff;
        --focus-outline: 3px solid #000;
    }
}

/* Тёмная тема */
@media (prefers-color-scheme: dark) {
    :root {
        --color-text: #f0f0f0;
        --color-bg: #1a1a1a;
    }
}

Позиционирование виджета

Виджет доступности обычно размещается в фиксированной позиции:

.accessibility-widget {
    position: fixed;
    bottom: 24px;
    right: 24px;
    z-index: 9000;
}

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

Срок реализации

3–5 дней: CSS-переменная система + React-компонент + тестирование каждого режима со screen reader.