Обычный сайт с контрастом 4.5:1 и стандартными размерами шрифта — это шаг к доступности, но не гарантия комфорта для пользователей с нарушениями зрения или моторики. Режим повышенной доступности решает эту проблему комплексно: увеличивает шрифт, повышает контраст до 7:1, отключает анимацию и увеличивает зоны кликабельности. Мы реализовали такое решение на базе CSS-переменных и React-компонента.
Почему стандартной доступности недостаточно?
Требования WCAG 2.1 — это минимум. Для текста размером меньше 18px нужен контраст 4.5:1, но пользователи с низким зрением часто предпочитают 7:1 и выше. Кроме того, стандартная доступность не учитывает индивидуальные предпочтения: кому-то нужен только крупный текст, кому-то — высокая контрастность, а кто-то страдает от анимации. Наш режим даёт выбор: пользователь сам решает, какие улучшения включить.
Как наши решения работают?
Основа — набор CSS-переменных, которые переопределяются при установке data-атрибута на html. Это позволяет моментально применять изменения ко всему интерфейсу. Переключение происходит без участия JavaScript — только через CSS.
| Опция | CSS-переменная | Влияние |
|---|---|---|
| Высокий контраст | --color-text, --color-bg, --focus-outline |
Контраст текста и фона не менее 7:1 |
| Увеличенный текст | --font-size-base |
Базовый размер шрифта увеличивается на 4px |
| Уменьшение анимации | --transition-duration и animation-duration: 0.01ms |
Все анимации и переходы отключаются |
| Увеличенные цели касания | --min-touch-target до 56px |
Кнопки и ссылки становятся крупнее, удобнее для моторных нарушений |
React-компонент управления
Мы написали хук useAccessibilityMode, который хранит выбранные режимы в localStorage и слушает системные медиа-запросы. Если в ОС включено уменьшение анимации, режим reduced-motion активируется автоматически.
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)
Часть улучшений применяется автоматически, если пользователь настроил свою ОС. CSS медиа-запросы переопределяют переменные при prefers-reduced-motion: reduce, prefers-contrast: more и prefers-color-scheme: dark. Это снижает нагрузку на браузер и экономит трафик — не нужно загружать дополнительный 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;
}
}
Что входит в реализацию режима доступности?
Результат работы включает:
- Набор CSS-переменных под ваш дизайн
- React-компонент с панелью управления
- Автоматическую интеграцию с системными настройками (prefers-*)
- Документацию по поддержке и настройке
- Инструкцию для пользователей по использованию режима
Мы также обучаем вашу команду: показываем, как добавлять новые опции и тестировать доступность. Наша команда имеет более 5 лет опыта в веб-доступности и реализовала более 30 проектов.
Процесс внедрения
| Этап | Длительность | Описание |
|---|---|---|
| Аудит текущей доступности | 1 день | Проверка контраста, размера текста, фокусов, работы с клавиатурой |
| Проектирование CSS-переменных | 1 день | Создание системы под ваш дизайн |
| Разработка компонента | 1–2 дня | Написание React-компонента или адаптация под архитектуру |
| Тестирование | 1 день | Проверка каждого режима со screen reader (NVDA, VoiceOver) и клавиатурой |
| Деплой и документация | 0.5 дня | Передача кода и инструкции по настройке |
Сроки и стоимость
Реализация занимает от 3 до 5 дней в зависимости от сложности сайта. Стоимость рассчитывается индивидуально — оценим ваш проект бесплатно. Гарантируем, что режим будет соответствовать WCAG 2.1 на уровне AA. Наш подход на CSS-переменных снижает трудозатраты на поддержку в 2 раза, что делает внедрение экономически эффективным.
Типичные ошибки при внедрении
- Игнорирование системных
prefers-*запросов — пользователь должен видеть изменения автоматически. - Переопределение фокуса только на CSS без видимого индикатора — обязательно оставляйте контур.
- Отсутствие сброса настроек — дайте пользователю возможность вернуть всё как было.
- Использование только JavaScript для переключения — наше решение на CSS-переменных в 2–3 раза быстрее и надёжнее.
Как убедиться, что режим работает во всех браузерах?
Мы тестируем решение на актуальных версиях Chrome, Firefox, Safari и Edge. CSS-переменные поддерживаются всеми современными браузерами, а медиа-запросы prefers-reduced-motion и prefers-contrast — в последних версиях. Для старых браузеров (IE11) предусмотрено graceful degradation: сайт остаётся доступным, но без расширенных опций.
Заключение
Режим повышенной доступности — это не роскошь, а необходимость для сайтов, ориентированных на всех пользователей. Свяжитесь с нами для консультации и оценки вашего проекта. Мы поможем сделать ваш сайт доступным и комфортным для каждого. Получите бесплатный аудит доступности и узнайте, как улучшить свой сайт.







