Семантические цветовые системы: именуйте цвета по назначению, а не по оттенку
Embed This Widget
Add the script tag and a data attribute to embed this widget.
Embed via iframe for maximum compatibility.
<iframe src="https://colorfyi.com/iframe/entity//" width="420" height="400" frameborder="0" style="border:0;border-radius:10px;max-width:100%" loading="lazy"></iframe>
Paste this URL in WordPress, Medium, or any oEmbed-compatible platform.
https://colorfyi.com/entity//
Add a dynamic SVG badge to your README or docs.
[](https://colorfyi.com/entity//)
Use the native HTML custom element.
Цветовая система, называющая основной цвет кнопки «синим», работает нормально — до тех пор, пока бренд не сменит цвет на зелёный. Теперь каждая ссылка на «синий» неверна, и каждый дизайнер и разработчик, работающий с кодовой базой, вынужден искать случаи, когда «синий» означает «интерактивный». Семантическое именование цветов решает эту проблему в корне: вместо того чтобы называть цвет по внешнему виду, его называют по выполняемой функции.
Это не косметическое различие. Оно меняет подход команд к принятию решений, реакцию продуктов на смену темы и степень доступности интерфейса в разных режимах.
Почему семантическое именование превосходит именование по оттенку
Проблема именования на практике
Большинство команд начинают с именования по оттенку. Руководство по стилю говорит: «Основной: blue-600. Дополнительный: gray-700. Ошибка: red-500.» Это выглядит чисто — и какое-то время является таковым. Проблема возникает, когда:
- Бренд меняется и «основной синий» становится фиолетовым
- Добавляется тёмный режим, где «красный ошибки» должен значительно осветлеть для сохранения контраста
- Белая метка продукта требует других цветов бренда без изменения логики компонентов
При именовании по оттенку каждый ребрендинг — это операция поиска и замены по всей кодовой базе. При семантическом именовании вы меняете значение --color-brand-primary в одном файле, и каждый использующий его компонент обновляется автоматически.
Семантические имена передают намерение
Переменная с именем --color-interactive-default сообщает о своей задаче: этот цвет маркирует элементы, с которыми пользователи могут взаимодействовать. Переменная blue-500 не говорит ничего, кроме того, как она выглядит. Когда разработчик видит color: var(--color-text-danger) в таблице стилей, он немедленно понимает: это текст в состоянии опасности. Видя color: #EF4444, ему нужно сверяться со спецификацией, чтобы понять, почему выбран именно этот красный.
Семантические имена делают код самодокументируемым. Они ускоряют дизайн-ревью, потому что все говорят на одном языке. Они снижают вероятность ошибок при передаче между дизайнерами и разработчиками.
Тёмный режим по своей природе семантичен
Тёмный режим — наиболее очевидный аргумент в пользу семантических систем. В светлом режиме --color-surface-default может быть #FFFFFF. В тёмном — #1E1E1E. Семантическое имя остаётся постоянным; меняется только значение. Если система построена вокруг имён оттенков, «белый» и «почти чёрный» не могут разделять одну семантическую роль — повсюду потребовалась бы условная логика вместо единой замены токена.
Примитивные и семантические токены цвета
Хорошо структурированная система цветовых токенов имеет как минимум два слоя: примитивные токены и семантические токены.
Примитивные токены: цветовая палитра
Примитивные токены — это ваша исходная цветовая палитра. Они не имеют мнения о том, где используются — они просто определяют все доступные в системе цвета. Типичная палитра может включать нейтральную шкалу, брендовую шкалу и утилитарные шкалы:
/* Примитивные токены — полная цветовая палитра */
--color-blue-50: #EFF6FF;
--color-blue-100: #DBEAFE;
--color-blue-200: #BFDBFE;
--color-blue-300: #93C5FD;
--color-blue-400: #60A5FA;
--color-blue-500: #3B82F6;
--color-blue-600: #2563EB;
--color-blue-700: #1D4ED8;
--color-blue-800: #1E40AF;
--color-blue-900: #1E3A8A;
--color-blue-950: #172554;
--color-green-50: #F0FDF4;
--color-green-500: #22C55E;
--color-green-700: #15803D;
--color-red-50: #FFF1F2;
--color-red-500: #EF4444;
--color-red-700: #B91C1C;
--color-yellow-50: #FEFCE8;
--color-yellow-500: #EAB308;
--color-yellow-700: #A16207;
--color-neutral-0: #FFFFFF;
--color-neutral-50: #F8FAFC;
--color-neutral-100: #F1F5F9;
--color-neutral-200: #E2E8F0;
--color-neutral-900: #0F172A;
--color-neutral-950: #020617;
Примитивные токены никогда не используются напрямую в коде компонентов. Они существуют исключительно как исходные значения для семантических токенов.
Семантические токены: цвета с назначением
Семантические токены ссылаются на примитивные токены и назначают им роли:
/* Семантические токены — назначение каждого цвета */
:root {
/* Бренд */
--color-brand-primary: var(--color-blue-600);
--color-brand-primary-hover: var(--color-blue-700);
--color-brand-primary-subtle: var(--color-blue-50);
/* Текст */
--color-text-default: var(--color-neutral-900);
--color-text-muted: var(--color-neutral-500);
--color-text-inverse: var(--color-neutral-0);
--color-text-danger: var(--color-red-700);
--color-text-success: var(--color-green-700);
--color-text-warning: var(--color-yellow-700);
--color-text-info: var(--color-blue-700);
/* Поверхности */
--color-surface-default: var(--color-neutral-0);
--color-surface-subtle: var(--color-neutral-50);
--color-surface-raised: var(--color-neutral-0);
--color-surface-overlay: var(--color-neutral-50);
/* Границы */
--color-border-default: var(--color-neutral-200);
--color-border-focus: var(--color-blue-600);
--color-border-danger: var(--color-red-500);
/* Состояния обратной связи */
--color-feedback-danger-surface: var(--color-red-50);
--color-feedback-danger-border: var(--color-red-500);
--color-feedback-danger-text: var(--color-red-700);
--color-feedback-success-surface: var(--color-green-50);
--color-feedback-warning-surface: var(--color-yellow-50);
--color-feedback-info-surface: var(--color-blue-50);
}
Таблицы стилей компонентов используют только семантические токены. Примитивные цвета не появляются в коде компонентов.
Паттерны цветов для успеха, предупреждения, ошибки и информации
Цвета обратной связи — наиболее распространённая отправная точка для семантических систем, поскольку их назначение очевидно. Никто не называет состояние ошибки #EF4444 из-за его оттенка — его выбирают, потому что он сигнализирует об опасности. Сделать это намерение явным в имени токена — небольшой шаг с большой отдачей.
Четыре категории обратной связи
Успех передаёт положительные результаты: форма отправлена, платёж обработан, файл загружен. Цвета успеха, как правило, зелёные, хотя варианты с бирюзовым и изумрудным тоже работают. Критическое требование — чтобы цвет воспринимался как позитивный в разных культурах: обычно это означает избегание жёлто-зелёных, выглядящих болезненно, и предпочтение чётких, насыщенных зелёных.
Полезное трио для успеха: - Поверхность: #F0FDF4 — очень светлый зелёный фон для баннеров успеха - Граница: #22C55E — видимая зелёная граница контейнера - Текст: #15803D — более тёмный зелёный для читаемого текста внутри
Предупреждение сообщает о риске, ещё не ставшем ошибкой: приближение к лимиту размера файла, истекающая сессия, действие с необратимыми последствиями. Жёлтые и янтарные традиционно сигнализируют осторожность, заимствуя у светофорных конвенций. Яркие жёлтые не проходят требования к контрасту на белом — всегда сочетайте жёлтый фон с тёмным янтарным или коричневым цветом текста.
Трио предупреждения, проходящее WCAG AA: - Поверхность: #FEFCE8 — бледный жёлтый фон - Граница: #EAB308 — видимая жёлтая граница - Текст: #713F12 — тёмный янтарный текст (достаточно тёмный для достаточного контраста)
Ошибка сообщает о сбое: неверный ввод, ошибка сервера, подтверждение деструктивного действия. Красные — почти универсальная конвенция. Искушение — использовать один красный, но состояния обратной связи лучше работают как трады — светлая поверхность, средняя граница и тёмный текст, — поскольку они компонуются в скрываемые баннеры, встроенную валидацию и комбинации иконка+текст без необходимости, чтобы цвет был единственным сигналом.
Информация передаёт нейтральные сведения: подсказки, ссылки на документацию, обновления прогресса без срочности. Синие работают хорошо, потому что разделяют цветовые ассоциации с интерактивностью, что уместно — состояния информации часто содержат ссылки или действия. Используйте достаточно отличающийся синий, чтобы информационные состояния сами по себе не воспринимались как интерактивные элементы.
Доступная реализация обратной связи
<!-- Доступное состояние ошибки: цвет + иконка + текст (три канала) -->
<div class="alert" role="alert" aria-live="polite">
<svg aria-hidden="true" class="alert-icon"><!-- иконка ошибки --></svg>
<p class="alert-message">
<strong>Платёж не прошёл.</strong>
Карта отклонена. Проверьте данные карты и попробуйте снова.
</p>
</div>
.alert {
display: flex;
gap: 0.75rem;
padding: 1rem;
border-radius: 0.375rem;
border-width: 1px;
border-style: solid;
background-color: var(--color-feedback-danger-surface);
border-color: var(--color-feedback-danger-border);
color: var(--color-feedback-danger-text);
}
Обратите внимание на трёхканальный подход: цвет (красная поверхность и граница), форма (иконка ошибки) и текст (описательное сообщение). Это удовлетворяет WCAG 1.4.1 — информация не передаётся только цветом.
Архитектура токенов: глобальные → алиасные → компонентные
Дизайн-системы корпоративного масштаба добавляют третий слой между примитивными и семантическими токенами: компонентные токены. Эта трёхуровневая архитектура часто называется «глобальные → алиасные → компонентные».
Уровень 1: Глобальные токены (примитивные)
Исходные значения. Числа, цвета, размеры шрифтов. Без мнений. Это атомы:
/* Глобальные / Примитивные */
--global-color-red-500: #EF4444;
--global-color-red-700: #B91C1C;
--global-space-4: 1rem;
--global-radius-md: 0.375rem;
Уровень 2: Алиасные токены (семантические)
Назначение ролей. Ссылаются на глобальные токены и дают им роли. Здесь живёт семантическое именование:
/* Алиасные / Семантические */
--alias-color-feedback-error-surface: var(--global-color-red-50);
--alias-color-feedback-error-border: var(--global-color-red-500);
--alias-color-feedback-error-text: var(--global-color-red-700);
Уровень 3: Компонентные токены
Назначения на уровне компонентов, ссылающиеся на алиасные токены. Они позволяют настраивать отдельный компонент без влияния на весь семантический слой:
/* Токены уровня компонента */
--input-border-color-error: var(--alias-color-feedback-error-border);
--input-text-color-error: var(--alias-color-feedback-error-text);
--alert-surface-color-error: var(--alias-color-feedback-error-surface);
Таблица стилей компонента использует только его собственные компонентные токены:
.input--error {
border-color: var(--input-border-color-error);
}
.input--error-message {
color: var(--input-text-color-error);
}
Это означает: если вы хотите настроить границу ошибки именно для инпутов — возможно, сделав её чуть темнее для лучшей видимости в конкретном макете формы, — вы меняете --input-border-color-error в файле токенов компонента, не трогая алиасный слой вообще.
Реализация в CSS-переменных и Tailwind
CSS-переменные
Полная CSS-реализация использует каскад, делающий тёмный режим элегантным:
:root {
/* Значения по умолчанию для светлого режима */
--color-surface-default: #FFFFFF;
--color-text-default: #0F172A;
--color-brand-primary: #2563EB;
--color-feedback-danger-surface: #FFF1F2;
--color-feedback-danger-border: #EF4444;
--color-feedback-danger-text: #B91C1C;
}
@media (prefers-color-scheme: dark) {
:root {
/* Переопределения для тёмного режима — те же имена токенов, другие значения */
--color-surface-default: #0F172A;
--color-text-default: #F8FAFC;
--color-brand-primary: #60A5FA;
--color-feedback-danger-surface: #450A0A;
--color-feedback-danger-border: #F87171;
--color-feedback-danger-text: #FCA5A5;
}
}
Каждый компонент продолжает ссылаться на те же имена токенов. Тёмный режим полностью управляется в объявлении :root — никакой условной логики в коде компонентов.
Интеграция с Tailwind CSS
CSS-первая конфигурация Tailwind v4 делает интеграцию семантических цветов простой. Определите семантические токены во входном файле стилей и ссылайтесь на них во всех утилитах Tailwind:
/* styles.css — Tailwind v4 */
@import "tailwindcss";
@theme {
--color-brand-primary: #2563EB;
--color-brand-primary-hover: #1D4ED8;
--color-brand-primary-subtle: #EFF6FF;
--color-text-default: #0F172A;
--color-text-muted: #64748B;
--color-text-danger: #B91C1C;
--color-surface-default: #FFFFFF;
--color-surface-subtle: #F8FAFC;
--color-feedback-danger-surface: #FFF1F2;
--color-feedback-danger-border: #EF4444;
}
В Tailwind v3 расширьте конфигурацию:
// tailwind.config.js
module.exports = {
theme: {
extend: {
colors: {
brand: {
primary: 'var(--color-brand-primary)',
'primary-hover': 'var(--color-brand-primary-hover)',
subtle: 'var(--color-brand-primary-subtle)',
},
feedback: {
'danger-surface': 'var(--color-feedback-danger-surface)',
'danger-border': 'var(--color-feedback-danger-border)',
'danger-text': 'var(--color-feedback-danger-text)',
},
},
},
},
}
Теперь Tailwind генерирует утилиты bg-brand-primary, text-feedback-danger-text и border-feedback-danger-border. Разметка шаблонов никогда не содержит исходного hex-значения:
<div class="rounded-md border border-feedback-danger-border bg-feedback-danger-surface p-4">
<p class="text-sm text-feedback-danger-text font-medium">
Это поле обязательно для заполнения.
</p>
</div>
Дизайн-токены в JSON для мультиплатформенных систем
Если команда работает на web, iOS и Android, данные токенов часто хранятся в платформенно-нейтральном JSON-формате и преобразуются в платформенно-специфические форматы (CSS-переменные, Swift-константы, Kotlin-константы) инструментом вроде Style Dictionary:
{
"color": {
"feedback": {
"danger": {
"surface": {
"$value": "#FFF1F2",
"$type": "color",
"$description": "Фон для состояний опасности/ошибки"
},
"border": {
"$value": "#EF4444",
"$type": "color",
"$description": "Цвет границы для состояний опасности/ошибки"
},
"text": {
"$value": "#B91C1C",
"$type": "color",
"$description": "Цвет текста внутри состояний опасности/ошибки. Проходит 4.5:1 на белом."
}
}
}
}
}
Style Dictionary читает этот JSON и генерирует CSS, Swift, Kotlin и любой другой формат, требуемый конвейером сборки. Команды, использующие Figma, могут синхронизировать JSON-токены напрямую с дизайн-файлами через плагин Tokens Studio, поддерживая дизайн и код в синхронизации.
Распространённые ошибки
Смешение слоёв именования в компонентах. Если компонент ссылается одновременно на --color-blue-600 (примитивный) и --color-brand-primary (семантический), дисциплина нарушается. Введите правило линтера или соглашение о код-ревью: код компонента может ссылаться только на семантические или компонентные токены.
Слишком много семантических ролей. Некоторые команды создают семантический токен для каждого контекста — --color-sidebar-background, --color-modal-background, --color-drawer-background — когда все три сопоставляются с одной поверхностью. Консолидируйте там, где цвета действительно разделяют назначение. Полезный тест: если два семантических токена всегда имеют одно и то же значение и всегда меняются вместе — объедините их.
Пропуск примитивного слоя. Без дисциплинированной примитивной палитры семантические токены ссылаются на исходные hex-значения напрямую. При желании скорректировать зелёную палитру нужно искать все семантические токены, ссылающиеся на любой зелёный hex. Примитивный слой делает это изменение единственной правкой.
Именование для сегодняшнего дизайна, а не для завтрашнего. Если сегодня --color-brand-primary — синий, будущий ребрендинг в фиолетовый по-прежнему сработает — семантическое имя остаётся допустимым. Но если вы назвали его --color-brand-blue, имя будет неверным в момент смены бренда. Держите семантические имена свободными от ссылок на оттенок везде, где это возможно.
Резюме
Семантические цветовые системы — это единовременная инвестиция, приносящая дивиденды каждый раз, когда продукт меняется. Ключевые принципы:
- Называйте цвета по назначению, а не по внешнему виду.
--color-text-dangerвместо--color-red. - Разделяйте примитивные токены (вся палитра) и семантические токены (назначение ролей).
- Ссылайтесь только на семантические токены в коде компонентов. Никогда не обращайтесь к примитивам напрямую.
- Управляйте тёмным режимом и темизацией на семантическом слое — компоненты остаются неизменными.
- Для крупных команд добавьте слой компонентных токенов для настройки на уровне компонента без нарушения семантического слоя.
Хорошо названная цветовая система превращает следующий ребрендинг, реализацию тёмного режима или вариант с белой меткой из миграции кодовой базы в изменение конфигурации.
Похожие цвета
Похожие бренды
Похожие инструменты
Генератор палитр
Генерируйте гармоничные цветовые палитры, используя комплементарные, аналоговые, триадные и расщеплённо-комплементарные схемы.
Проверка контрастности
Проверяйте коэффициенты контрастности цветов в соответствии с рекомендациями WCAG 2.1. Тестируйте соответствие AA и AAA для обычного и крупного текста.