ГлавнаяИнструментыПродуктовый дизайнПалитра для сайта
Цветовая палитра для сайта из одного фирменного цвета
Вставьте фирменный цвет — получите готовый набор ролей: фон, карточки, границы, основной и приглушённый текст, акцент с наведением и нажатием, кольцо фокуса, четыре статусных цвета и всё то же самое для тёмной темы. Каждая пара «текст на фоне» проверяется по WCAG 2.2 и, если не проходит, подтягивается по светлоте до 4,5:1. Копируете CSS-переменные — и верстаете.
—
Как это выглядит
Роли и их значения
Проверка контраста
Текст на фоне — 4,5:1, границы и кольцо фокуса — 3:1. Ниже порога ничего не остаётся: цвет сдвигается по светлоте, пока не пройдёт.
Метод. Фирменный цвет переводится в OKLCH; нейтральные тона получают долю его оттенка, акцент берётся с той ступени шкалы, где он проходит 4,5:1 на своём фоне, статусные цвета строятся на фиксированных углах оттенка. Контраст — коэффициент WCAG 2.2, без округления вверх.
Расчёт идёт в вашем браузере — введённые данные никуда не отправляются.
Как пользоваться
- Вставьте фирменный цветHEX из брендбука, значение из Figma или что угодно, что понимает CSS. Если цвета ещё нет — покрутите поле выбора: палитра пересобирается на каждое изменение.
- Посмотрите на превьюСлева светлая тема, справа тёмная: текст, ссылка, кнопка с наведением, поле в фокусе и четыре статуса. Это тот же набор переменных, что уедет в код, — видно сразу, а не после вёрстки.
- Проверьте таблицу парКаждая пара «что на чём» посчитана по WCAG. Если исходный цвет не проходит, он сдвигается по светлоте: в колонке видно итоговое значение и насколько оно выше порога.
- Заберите переменныеCSS-переменные идут вместе с блоком prefers-color-scheme и селектором [data-theme="dark"] — тёмная тема включится сама и останется переключаемой вручную.
Почему интерфейсу нужны роли, а не оттенки
Палитра из десяти оттенков одного цвета — это ещё не тема. Когда верстальщик открывает такой набор, у него остаётся тот же вопрос: какой шаг взять для текста, какой для границы поля и что делать с кнопкой под курсором. Дальше каждый решает сам, и через полгода в проекте живут четыре серых и три синих.
Роль снимает вопрос: у каждого места в интерфейсе одна переменная и одно правило. Набор, который выдаёт этот инструмент:
Нейтральные тона не чисто серые: в них подмешана доля оттенка фирменного цвета — около 1–2 % хромы в OKLCH. Разницу трудно назвать, но интерфейс перестаёт выглядеть так, будто серую сетку сверстали отдельно от бренда.
Чем это отличается от шкалы 50–900
Шкала — материал, тема — изделие. Если нужна именно шкала, чтобы потом назначать роли руками, возьмите генератор палитры 50–900: он строит десять шагов в OKLCH и показывает контраст каждого с белым и чёрным. Здесь шкала считается внутри и сразу превращается в роли — с состояниями, фокусом, статусами и тёмной темой.
Что проверяется и почему цвет иногда меняется
Для каждой пары «что на чём» считается коэффициент контрастности WCAG 2.2:
Пороги разные, и это не придирка: 4,5:1 нужен основному тексту (критерий 1.4.3), 3:1 — крупному тексту, границам полей, иконкам и кольцу фокуса (1.4.11). Кольцо фокуса проверяется дважды: против фона страницы и против поверхности карточки, потому что поля ввода живут и там, и там.
Если пара не проходит, цвет сдвигается по светлоте OKLCH — шагами по 0,5 %, пока не наберёт нужное значение. Оттенок и насыщенность остаются, меняется только светлота, поэтому цвет продолжает читаться как фирменный.
Чаще всего сдвиг случается с кнопкой. Средне-светлый фирменный цвет — голубой, бирюзовый, салатовый, жёлтый — не держит белый текст: на #2f6fed белый даёт около 4,9:1 и проходит, а на #22c55e всего 2,1:1. Инструмент затемняет заливку до первого значения, которое проходит, и честно пишет об этом в выводе. Исходный оттенок при этом никуда не девается: он остаётся в тонированных плашках, границах и акцентных иконках.
Отдельную пару — например, цвет из старого макета на нестандартном фоне — быстрее проверить в проверке контраста цветов: там же видно, насколько нужно сдвинуть цвет, чтобы пройти.
Тёмная тема, а не инверсия светлой
Тёмная тема, полученная фильтром invert() или простой заменой чёрного на белый, выглядит неопрятно: чистый белый текст на чистом чёрном даёт 21:1 и режет глаза, а тени и полупрозрачные слои превращаются в грязь.
Здесь тёмная тема строится отдельно, по тем же правилам:
- Фон не чёрный. Светлота около 19 % в OKLCH: на нём видно карточку, вложенную поверхность и границу — три уровня, которые на чистом чёрном сливаются.
- Текст не белый. Светлота около 95 % даёт примерно 15:1 вместо 21:1 — запас есть, ореола вокруг букв нет.
- Акцент светлее, чем в светлой теме. Тёмно-синяя ссылка на тёмном фоне не читается, поэтому для ссылок берётся шаг из верхней половины шкалы, а заливка кнопки остаётся насыщенной, чтобы белый текст на ней по-прежнему проходил.
- Статусные плашки — тёмные, текст — светлый. Светло-зелёный фон, перенесённый из светлой темы, в тёмной выглядит как дыра в экране.
Экспорт кладёт тёмные значения и в @media (prefers-color-scheme: dark), и в :root[data-theme="dark"]. Первое включает тему по системной настройке, второе даёт переключатель; селектор :root:not([data-theme="light"]) в медиазапросе следит за тем, чтобы ручной выбор светлой темы не был перебит системным.
Как подключить и не развалить через полгода
- Один источник значений. Переменные объявляются в
:rootодин раз. В компонентах нет ни одного HEX:background: var(--ui-surface),color: var(--ui-text). - Фокус не отключают.
outline: 2px solid var(--ui-focus); outline-offset: 2pxна:focus-visible— этого достаточно, чтобы клавиатура работала во всём интерфейсе. - Состояния — из палитры, а не из
opacity. Полупрозрачная кнопка под курсором меняет контраст с текстом непредсказуемо;--ui-accent-hoverпросчитан. - Тонированные блоки — парой. Фон
--ui-accent-softживёт только вместе с текстом--ui-on-accent-soft. Это единственная пара, где акцентный цвет можно ставить на акцентный фон. - Графики и иллюстрации — отдельная история. Категориальным цветам на диаграмме нужен контраст друг с другом, а не с фоном, и роли из этой палитры для них не годятся.
Если интерфейс уже сверстан и вопрос в том, куда попадают подсказки и туры онбординга, посмотрите как их добавляют без разработчика: они наследуют те же переменные и поэтому выглядят частью продукта.
Источники
- W3C. Web Content Accessibility Guidelines (WCAG) 2.2 — критерии 1.4.3, 1.4.6, 1.4.11; определения относительной яркости и коэффициента контрастности.
- W3C. CSS Color Module Level 4 — запись oklch() и приведение к охвату sRGB уменьшением хромы.
- Ottosson B. A perceptual color space for image processing, 2020 — пространства OKLab и OKLCH.
- W3C. CSS Color Adjustment Module Level 1 — свойство color-scheme и медиазапрос prefers-color-scheme.
Частые вопросы
Чем этот инструмент отличается от генератора палитры 50–900?
Генератор палитры выдаёт шкалу оттенков одного цвета — материал, из которого дизайнер собирает тему. Здесь на выходе сразу роли: фон, поверхности, границы, текст, акцент с состояниями, фокус, статусы и тёмная тема. Шкала считается внутри как промежуточный шаг.
Почему цвет кнопки не совпадает с моим фирменным?
Потому что на исходном цвете белый текст не набирает 4,5:1. Цвет затемняется по светлоте OKLCH до первого значения, которое проходит; оттенок и насыщенность сохраняются. Исходный цвет остаётся в тонированных плашках, границах и акцентных иконках, где порог ниже.
Можно ли обойтись без тёмной темы?
Да, снимите галочку — экспорт останется только светлым, а свойство color-scheme будет объявлено как light. Добавить тёмную тему позже можно в любой момент: значения зависят только от фирменного цвета.
Подойдёт ли палитра для Tailwind?
Для Tailwind v4 выберите экспорт «@theme»: переменные вида --color-ui-accent становятся классами bg-ui-accent, text-ui-text и так далее. Для v3 возьмите обычные CSS-переменные и сошлитесь на них в theme.extend.colors.
Что делать, если фирменных цветов два?
Соберите тему по основному цвету, а второй заведите как отдельную акцентную роль: постройте палитру по нему, возьмите оттуда --accent, --accent-solid и пару для плашки и переименуйте в --ui-accent-2. Роли фона, текста и границ должны остаться одни на весь интерфейс.
Достаточно ли WCAG AA для интерфейса?
AA — это минимум, с которого начинают, и именно его требуют закупки и большинство корпоративных чек-листов. Для длинных текстов и интерфейсов, которыми пользуются весь день, стоит целиться в 7:1 для основного текста: в таблице видно, у каких пар уже есть такой запас.
Ещё в разделе «Продуктовый дизайн»
- Проверка контраста цветов
Проходит ли пара цветов текста и фона WCAG AA или AAA?
- Генератор доступной палитры
Как получить доступную палитру, где контраст проверен для каждого оттенка?
- Генератор типографической шкалы
Какие размеры шрифта дают стройную адаптивную типографическую шкалу?
- Время чтения подсказок и тура
Успеет ли пользователь прочитать подсказку или шаг тура?
- Проверка текста подсказки
Достаточно ли подсказка короткая, понятная и ведёт ли к действию?
- Калькулятор SUS
Какой балл SUS у интерфейса и хорошее ли у него юзабилити?