Главная идея
Обычный медиа-запрос (min-width) спрашивает у браузера: «какого размера экран?». Запросы prefers-* спрашивают другое: «что предпочитает сам человек?». Эти настройки пользователь задаёт один раз в операционной системе — тёмную тему, уменьшение анимаций, высокий контраст — а каждый сайт может их прочитать и подстроиться. Это и есть доступность на уровне CSS: не навязывать, а уважать выбор пользователя.
Представь умный дом. Жилец один раз настроил под себя: вечером — приглушённый свет (тёмная тема), он плохо переносит мигание — значит без резких световых эффектов (reduced motion), а у пожилого родственника слабое зрение — нужен максимально чёткий, контрастный свет (more contrast). Сайт с prefers-* ведёт себя как такой умный дом: он спрашивает у системы настройки жильца и подстраивается под него, а не заставляет каждого подгонять себя под один общий режим.
Светлая и тёмная тема рядом
Одна и та же карточка, два набора цветов. CSS выбирает набор по системной настройке — пользователю не нужно ничего нажимать:
Палитры удобно держать в CSS-переменных и переопределять их внутри медиа-запроса. Цветовые пары «светлая → тёмная»:
#2458d3 на тёмном фоне «горит» и плохо читается. На тёмном нужен светлее и спокойнее — #93c5fd. Контраст подбирают для каждой темы отдельно.Как это работает: reduced-motion и contrast
prefers-reduced-motion: reduce — это не каприз, а медицинская необходимость для людей с вестибулярными расстройствами: параллакс, резкие зумы и автопрокрутка могут вызвать головокружение и тошноту. Правильный подход — не вырезать функциональность, а обезвредить движение: свести длительность анимаций и переходов к мгновенным. Интерфейс остаётся тем же, просто без укачивания.
prefers-contrast: more усиливает читаемость для слабовидящих: добавляют видимые границы, делают цвета насыщеннее, убирают полупрозрачность. Здесь нельзя «на глаз» — контраст текста к фону проверяют по WCAG (минимум 4.5:1 для обычного текста).
Когда применять
- Всегда объявляйте
color-schemeна:root— иначе скроллбары и системные поля останутся светлыми в тёмной теме. - Отключайте не все эффекты, а только движение, которое может мешать.
- Контраст проверяйте на реальных цветах, особенно у ссылок, кнопок и карточек.
Базовый CSS
:root {
color-scheme: light dark;
--bg: #ffffff;
--text: #172033;
--accent: #2458d3;
--space-section: clamp(3rem, 8vw, 7rem);
}
body {
background: var(--bg);
color: var(--text);
}
.hero {
display: grid;
gap: clamp(1rem, 3vw, 3rem);
padding-block: var(--space-section);
}
@media (min-width: 64rem) {
.hero {
grid-template-columns: 1fr 1fr;
align-items: center;
}
}
@media (prefers-color-scheme: dark) {
:root {
--bg: #111827;
--text: #f8fafc;
--accent: #93c5fd;
}
}
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms;
transition-duration: 0.01ms;
scroll-behavior: auto;
}
}
@media (prefers-contrast: more) {
:root {
--accent: #003cff;
}
.card {
border: 2px solid currentColor;
}
}