Доступность с CSS
Вы уже умеете раскладку, движение и современные приёмы. Доступность в CSS — это слой, который люди ощущают: видно ли, где фокус клавиатуры? читается ли текст? не вызывает ли крутящаяся анимация тошноту? Эта сессия — не свалка HTML (landmarks, alt, ARIA). Здесь привычки стиля, которые держат фокус, контраст и движение пригодными к использованию.
Фокус должен оставаться видимым
Пользователь клавиатуры проходит ссылки и элементы управления через Tab. Если кольцо фокуса исчезло — он потерян. Предпочитайте :focus-visible: клики мышью остаются спокойными, а фокус с клавиатуры — заметным:
:root {
--focus-ring: #2563eb;
}
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
outline: 3px solid var(--focus-ring);
outline-offset: 3px;
}
.text-link:focus:not(:focus-visible) {
outline: none;
}
:focus-visible срабатывает там, где кольцо действительно помогает (обычно клавиатура). Дайте высококонтрастное кольцо и небольшой outline-offset, чтобы оно не сливалось с рамками.
Никогда не ставьте outline: none без замены
Убрать стандартный outline можно только если вы даёте более ясный свой стиль фокуса. Голый *:focus { outline: none; } — классическая ловушка:
/* Bad: keyboard users lose the only cue */
.bad-button:focus {
outline: none;
}
/* Good: custom ring that still shows focus */
.good-button:focus-visible {
outline: none;
box-shadow: 0 0 0 3px #fff, 0 0 0 6px #0f766e;
}
Если вы глушите outline браузера, что-то другое должно помечать сфокусированный элемент — box-shadow, цвет рамки или сдвиг фона, который остаётся очевидным на любой теме.
Контраст — это решение CSS
Фирменные цвета эффектны на макете и тускнеют на телефоне под солнцем. Относитесь к парам передний план / фон как к решению доступности, а не только к декору:
:root {
--surface: #0f172a;
--text: #f8fafc;
--muted: #cbd5e1;
--accent: #38bdf8;
--accent-text: #0c4a6e;
}
.hero {
background: var(--surface);
color: var(--text);
}
.hero .lede {
color: var(--muted);
}
.hero .cta {
background: var(--accent);
color: var(--accent-text);
font-weight: 700;
}
Для основного текста и кнопок целитесь в сильный контраст. Декоративные серые тона допустимы на второстепенных подписях, но первичный текст и элементы управления должны оставаться читаемыми. Перед релизом палитры проверьте пары чекером контраста.
Уважайте уменьшенное движение
Анимации и крупные трансформации могут вызывать дискомфорт. Несущественное движение оборачивайте в prefers-reduced-motion:
.banner {
transition: transform 0.4s ease, opacity 0.4s ease;
}
.banner.is-shown {
transform: translateY(0);
opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
.banner,
.banner.is-shown {
transition: none;
transform: none;
}
.spinner {
animation: none;
}
}
Кто попросил ОС уменьшить движение, всё равно должен получить конечное состояние интерфейса — просто без «пути» анимации. Нужные смены opacity или раскладки оставьте; бесконечные вращения и крупные слайды уберите.
Высокий контраст и forced-colors
Некоторые среды переписывают вашу палитру (Windows High Contrast / forced-colors). Смягчите хрупкий декор и держите настоящие границы:
.card {
border: 1px solid #e2e8f0;
background: #fff;
box-shadow: 0 8px 24px rgb(15 23 42 / 12%);
}
@media (forced-colors: active) {
.card {
border: 1px solid CanvasText;
background: Canvas;
box-shadow: none;
color: CanvasText;
}
.card a {
color: LinkText;
}
}
Системные цветовые ключевые слова вроде Canvas, CanvasText и LinkText помогают элементам оставаться видимыми, когда цвета задаёт пользователь — а не ваш брендбук.
Чеклист со стороны CSS
📊 CSS accessibility habits
| Practice | CSS habit | Avoid |
|---|---|---|
| Keep focus findable | :focus-visible + strong ring / shadow |
outline: none with no replacement |
| Readable type | High-contrast text/background tokens | Light grey on white for body copy |
| Kind motion | @media (prefers-reduced-motion: reduce) |
Endless spins for everyone |
| Survive high contrast | Real borders; forced-colors tweaks |
Shadow-only “edges” |
| Reachable controls | Comfortable padding / hit area | Tiny icon-only targets with no focus style |
HTML по-прежнему отвечает за landmarks, подписи и alt. CSS решает, остаются ли эти элементы воспринимаемыми после стилизации.
Skip-ссылки и focus-within
Skip-ссылка перепрыгивает повторяющуюся «шапку». Стилизуйте её так, чтобы она появлялась при фокусе. :focus-within может подсветить целую группу, когда фокус у дочернего элемента:
.skip-link {
position: absolute;
left: 1rem;
top: -3rem;
padding: 0.5rem 0.75rem;
background: #111827;
color: #fff;
border-radius: 0.375rem;
z-index: 20;
}
.skip-link:focus-visible {
top: 1rem;
outline: 3px solid #fbbf24;
outline-offset: 2px;
}
.nav:focus-within {
box-shadow: inset 0 0 0 2px #2563eb;
}
Skip-ссылка остаётся за экраном, пока нет фокуса, затем становится очевидной. Кольцо у nav помогает, когда Tab попадает на дочернюю ссылку внутри панели.
Попробуйте сами
- Добавьте кольцо
:focus-visibleссылкам и кнопкам; пройдите страницу Tab’ом и убедитесь, что фокус всегда виден. - Возьмите одну слабоконтрастную пару и исправьте её более тёмным текстом или более глубокой поверхностью.
- Оберните transition или animation в
prefers-reduced-motion: reduceи переключите настройку ОС (или эмуляцию DevTools). - В эмуляции forced-colors проверьте, что у карточек остаётся настоящая граница.
- Стилизуйте skip-ссылку, которая появляется только при фокусе с клавиатуры.
Типичные ошибки
- Глобальный
outline: none(илиoutline: 0) без своего стиля фокуса - Красивые фирменные цвета, которые проваливают контраст на тексте и основных кнопках
- Крупные анимации для всех без шлюза
prefers-reduced-motion - Скрытие фокусируемого элемента одним
opacity: 0, пока он всё ещё принимает Tab - Восприятие этого урока CSS как полной замены семантического HTML и ARIA
Итог
- Держите фокус клавиатуры видимым — предпочитайте
:focus-visibleи не стирайте outline без более сильной подсказки - Относитесь к контрасту цвета как к требованию для текста и элементов управления
- Уважайте
prefers-reduced-motionи укрепляйте стили дляforced-colors - Стилизуйте skip-ссылки и используйте
:focus-within, где группе нужен общий сигнал - Дальше: Итоги CSS и следующие шаги (
summary) — завершите курс перед мини-проектом
🧠 Проверьте Свои Знания
Проверьте Свои Знания
Бросьте себе вызов с помощью этой интерактивной викторины и узнайте, насколько хорошо вы понимаете тему
📝 Инструкции
- Внимательно прочитайте каждый вопрос
- Выберите лучший ответ на каждый вопрос
- Вы можете пересдавать тест столько раз, сколько захотите
- Ваш прогресс будет показан вверху