Цветовая система и контраст: палитра, которую можно прочитать

Зачем:Вы соберёте палитру, которая выглядит цельно и читается людьми со слабым зрением, и проверите контраст числами, а не на глаз. После урока вы знаете роли цветов, умеете строить ступени из одного оттенка и сделаете светлую и тёмную темы.

25 минут

Озвучено синтезом речи (Qwen3-TTS), голос не принадлежит человеку.

Цветовая система — набор ступеней и ролей (фон, текст, акцент, смысловые цвета), из которого берут все цвета. Контраст текста с фоном измеряют по WCAG.

Цвет как система

Цвет на сайте не выбирают «каждый раз по ситуации». Если у кнопки на одной странице синий один, а на другой другой, посетитель перестаёт понимать, что кнопка. Поэтому цвета собирают в систему: набор ступеней и ролей, из которого берут все значения.

Ролей обычно четыре.

  • Поверхность: фон страницы, карточек и панелей.
  • Текст: основной и вторичный (подписи, пояснения).
  • Акцент: то, на что вы хотите, чтобы нажали: главная кнопка и ссылки.
  • Смысловые цвета: ошибка, успех, предупреждение, подсказка. У них по умолчанию красный, зелёный, жёлтый и синий, и они не должны совпадать с акцентом.

Названия берут по роли, а не по виду: --accent, а не --blue. Если завтра акцент станет зелёным, правилу о главной кнопке это не помешает.

Работа идёт в таком порядке: сначала нейтральные ступени (от почти белого до почти чёрного, из них собирают фон и текст), потом ступени акцента, потом смысловые цвета, потом тёмная тема. Цвет в итоге занимает мало места: у большинства хороших страниц это 90 % нейтрального, немного акцента и вкрапления смысловых.

Проверьте себя: почему цвета называют по роли, а не по виду?

Чтобы можно было сменить цвет, не переписывая правила: роль («главное действие») остаётся, меняется только значение.

Ступени из одного оттенка

Вместо одного синего берут ряд: от очень светлого до очень тёмного, обычно одиннадцать ступеней (50, 100, 200 и так до 900 и 950). Фон делают из светлых, текст из тёмных, акцент из средних.

В HEX или RGB ряд строить неудобно: у разных оттенков одинаковый «номер» выглядит по-разному светлым. В OKLCH светлота воспринимается равномерно, поэтому ряд из равных шагов светлоты даёт ровную лестницу у любого оттенка. Три числа: светлота (L от 0 до 1), насыщенность (C, примерно до 0,4) и оттенок (H в градусах). Подробнее вы встречали их в уроке о типографике и цвете.

Подвигайте оттенок и насыщенность. Ступени строятся автоматически, а ниже для каждой пары «текст на фоне» считается контраст.

Палитра из одного оттенка и проверка контраста

Так выглядит страница в этой теме

Обычный текст и ссылка с подчёркиванием.

Главное действие
Контраст пар по формуле WCAG (нужно не меньше 4,5 к 1 для обычного текста)
ПараЦветаКонтрастИтог
Основной текст (нейтральный 900 на 50)#2c3136 / #f5f9fd12.42 к 1✓ AAA
Вторичный текст (нейтральный 700 на 50)#565b62 / #f5f9fd6.44 к 1✓ AA
Ссылка (акцент 700 на 50)#275b9a / #f5f9fd6.48 к 1✓ AA
Кнопка: белый текст на акценте 600#ffffff / #3672bc4.88 к 1✓ AA
Слишком светлый акцент 300 на 50#a3cafd / #f5f9fd1.59 к 1✕ не проходит

Заметьте: ступени подобраны по одинаковому шагу светлоты, поэтому роли держатся на одних и тех же номерах при любом оттенке. А в тёмной теме те же роли играют другие ступени: это не инверсия, а новая раскладка. Если пара не проходит при каком-то оттенке, сдвиньте ступень на одну в сторону темноты (для светлой темы) или светлоты (для тёмной).

Проверьте себя: чем OKLCH удобнее HEX для ступеней?

Светлота в OKLCH воспринимается равномерно: равный шаг даёт равное изменение на глаз у любого оттенка.

Контраст считают, а не оценивают на глаз

Почему на глаз контраст не оценить и что такое отношение яркостей текста и фона (от 1 к 1 до 21 к 1, чёрное на белом), вы знаете из урока о типографике и цвете; там же главная ошибка: светло-серый текст на белом. Здесь те же пороги с номерами критериев WCAG 2.2, на которые ссылаются проверяющие:

  • 4,5 к 1 для обычного текста (критерий 1.4.3, минимальный контраст);
  • 3 к 1 для крупного (от 24 пикселей или от 18,66 пикселя жирным);
  • 3 к 1 для значков, границ полей и других частей интерфейса (критерий 1.4.11).

Формула такая: сначала из каждого цвета считают относительную яркость (с учётом того, что экран не линеен), затем делят яркую на тёмную, прибавив к обеим по 0,05. Вам считать руками не нужно: есть сервисы (WebAIM Contrast Checker, в источниках), а инструменты разработчика браузера показывают отношение прямо при выборе цвета. Таблица на схеме выше использует ту же формулу, и вы можете проверить её у себя.

Что полезно помнить:

  • Текст на картинке или градиенте. Проверять надо в самом светлом месте под буквами, а надёжнее подложить сплошную полупрозрачную плашку.
  • Состояния. Кнопка при наведении и фокусе тоже должна проходить.
  • Готовится новый метод оценки, APCA (в черновиках WCAG 3). Пока официальный стандарт, на который ссылаются законы и проверяющие, это отношение яркостей из WCAG 2.
Проверьте себя: какой контраст нужен обычному тексту?

Не меньше 4,5 к 1; крупному тексту и значкам хватает 3 к 1.

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

Около одного мужчины из двенадцати и значительно меньше женщин не различают часть цветов, а ещё есть люди с нарушениями зрения и просто яркое солнце. Поэтому смысл нельзя передавать только цветом (критерий 1.4.1):

  • ошибке нужны слово или значок («Ошибка: телефон указан неверно»), а не только красная рамка;
  • ссылке в тексте нужно подчёркивание, а не только другой цвет;
  • на графике разные линии различают формой точек или подписью, а не только оттенком.

Светлая и тёмная темы

Тёмная тема не инверсия светлой. Просто взять и заменить белое на чёрное нельзя по трём причинам. Чистый чёрный и чистый белый режут глаз сильнее, чем тёмно-серый и тёплый светлый. Насыщенные цвета на тёмном «вибрируют». Тени на тёмном не видны, поэтому высоту показывают светлее фона, а не темнее.

Поэтому для тёмной темы те же роли играют другие ступени: фон ступень 950, текст ступень 100, акцент ступень 300–400. Включают её по настройке системы человека.

@media (prefers-color-scheme: dark) {
  :root {
    --surface: #14130f;
    --text: #f2efe9;
  }
}

И обязательно скажите браузеру, что страница умеет обе темы, метатегом <meta name="color-scheme" content="light dark">: тогда поля формы и полосы прокрутки тоже перекрасятся. У body задавайте явный фон: иначе тёмный текст может оказаться на тёмном.

Проверить правило @media автоматически мы не можем, поэтому в практике тёмная тема сделана блоком [data-theme="dark"] прямо на странице: так вы увидите обе темы рядом.

Практика

На странице вашего проекта сейчас бледные цвета. Соберите палитру и перекрасьте страницу, проверяя пары по таблице контраста. Все цвета пока записывайте прямо в правила: так проверка контраста читает их однозначно. В следующих уроках вы замените их переменными, и страница перекрасится целиком одним изменением.

Заодно сделайте сообщение об ошибке, которое понятно и без цвета, и тёмный блок с отдельной раскладкой ступеней.

Что было не так с 2014 годом

В 2014 году тёмных тем в браузерах не было, и контраст проверяли редко: плоский дизайн любил светло-серый на белом. Требование WCAG о контрасте существует с 2008 года, но его включали в тендеры и законы значительно позже. Сегодня оно проверяется автоматически, и страница с серым текстом не пройдёт проверку.

Практика

Готовлю вашу страницу…

Тест

Вопрос 1 из 6

Какой контраст требует WCAG для обычного текста и для крупного?

Один ответ

Карточки

Эти карточки попадут в повторение, когда вы завершите урок.

  • Какой контраст нужен тексту?

    Ответ

    Не меньше 4,5 к 1 для обычного, 3 к 1 для крупного (от 24 px или 18,66 px жирным) и для значков и границ полей (WCAG 2.2).

  • Какие роли у цветов в системе?

    Ответ

    Поверхность (фон), текст, акцент (главное действие, ссылки) и смысловые цвета (ошибка, успех, предупреждение). Цвета называют по роли, а не по виду.

  • Зачем OKLCH?

    Ответ

    В нём светлота воспринимается равномерно, поэтому ступени из одного шага светлоты равны на глаз у любого оттенка.

  • Как делают тёмную тему?

    Ответ

    Не инверсией: другими ступенями для тех же ролей. Фон тёмно-серый, текст не чисто белый, акцент светлее. Включают через prefers-color-scheme.

  • Можно ли передавать смысл только цветом?

    Ответ

    Нет. Ошибка получает слово или значок, ссылка подчёркивание: так смысл доступен и тем, кто не различает цвета.

Источники

Дальше

Теперь вы знаете: цветовая система, контраст в цветовой системе: роли, состояния, текст на картинке.