Контраст и смысл без опоры только на цвет
Цвет помогает различать разделы, ссылки и состояния. Но учебная информация должна оставаться понятной, если два оттенка воспринимаются одинаково или фон и текст плохо различимы. Поэтому рассмотрим две задачи отдельно: достаточную разницу яркости и наличие другого способа понять значение. Хороший контраст не объясняет, что означает зелёная метка, а понятное слово не делает бледный текст читаемым.
В a11y-lab уже существуют статья, таблица и клавиатурный индикатор. Используем их для выбора цветовых пар. Мы не меняем палитру действующего ProfessorWeb и не объявляем все его элементы проверенными. Учебные цвета служат исходными данными для разбора; окончательное оформление библиотеки требует отдельного рассмотрения реальных сочетаний и состояний.
Проверяется пара, а не отдельный цвет
У утверждения «фиолетовый доступен» нет достаточного смысла. Текст этого цвета может хорошо различаться на белом и теряться на тёмной панели. Для оценки нужно знать цвет текста и фон, а при прозрачности — итоговое сочетание. Если фон представлен изображением или градиентом, одна удачная точка не описывает все положения надписи.
Для обычного текста на уровне AA критерий Contrast Minimum задаёт отношение не менее 4,5:1, для крупного текста — 3:1. Определение крупного текста и исключения следует брать из критерия, а не из субъективного впечатления «этот заголовок большой». Значение у порога нельзя округлять в сторону прохождения: 4,499:1 не становится достаточным только потому, что интерфейс показал одну цифру после запятой.
Рассмотрим учебную пару: чёрный текст на белом фоне. Относительная яркость белого равна единице, чёрного — нулю. После добавления принятого в формуле смещения получается (1 + 0.05) / (0 + 0.05), то есть 21. Это расчёт для заданных значений, а не измерение страницы в браузере. Он помогает понять направление отношения: более светлое значение стоит в числителе.
Для собственных непрозрачных RGB-пар можно использовать следующий полный учебный вычислитель. Сохраните его отдельно как contrast.js, если хотите позже выполнить расчёт. Он принимает только шестизначные HEX-цвета и не анализирует CSS страницы, прозрачность или изображения:
function luminance(hex) {
if (!/^#[0-9a-f]{6}$/i.test(hex)) {
throw new Error('Ожидается цвет вида #RRGGBB');
}
const values = [1, 3, 5].map(offset => {
const component = parseInt(hex.slice(offset, offset + 2), 16) / 255;
return component <= 0.04045
? component / 12.92
: ((component + 0.055) / 1.055) ** 2.4;
});
return 0.2126 * values[0] + 0.7152 * values[1] + 0.0722 * values[2];
}
function contrast(first, second) {
const a = luminance(first);
const b = luminance(second);
return (Math.max(a, b) + 0.05) / (Math.min(a, b) + 0.05);
}
console.log(contrast('#000000', '#ffffff'));
console.log(contrast('#56318c', '#ffffff'));
Первый вызов имеет ожидаемое значение 21. Второй вычисляет пару для акцента нашего стенда; заранее приписывать ему результат измерения не требуется. Перевод компонентов в линейное представление отличается от простого среднего трёх чисел. Поэтому сравнение «этот HEX выглядит темнее» не заменяет расчёт, особенно для насыщенных цветов.
Скрипт не определяет соответствие всего документа. Он отвечает на один вопрос о двух известных непрозрачных цветах. Чтобы связать результат со страницей, нужно установить действительные значения, размер и насыщенность шрифта, фон и состояние элемента. Если поверх фона наложена полупрозрачная панель, сначала необходимо получить итоговый цвет, а не передавать её исходный HEX как будто она непрозрачна.
Ссылка должна оставаться узнаваемой
Теперь рассмотрим абзац с переходом к старому уроку. Если единственная разница ссылки и текста — оттенок, читатель может не различить её как действие. Сохраним обычное подчёркивание и явное изменение при фокусе. В конец lesson.css добавьте:
article a {
color: #56318c;
text-decoration: underline;
text-underline-offset: 0.18em;
}
article a:hover, article a:focus {
text-decoration-thickness: 0.15em;
}
Подчёркивание обозначает назначение без необходимости различать оттенок. Индикатор фокуса из предыдущих уроков сохраняет положение выбранного элемента. Эти два признака решают разные задачи: узнавание всех ссылок в абзаце и понимание текущего выбора. Не стоит заменять оба одной едва заметной сменой цвета при наведении.
Требование Use of Color относится к передаче информации без единственной опоры на цвет. Оно не означает запрет цветовых акцентов. Цвет может усиливать существующее название и форму, пока существенный смысл доступен также другим способом. Поэтому узнаваемую палитру сайта можно сохранить, уточнив роли и конкретные сочетания.
Сообщение должно объяснять состояние
Представим учебное сообщение о неполном результате отбора. Если рядом поставить только красную точку, читатель должен знать легенду и различать цвет. Полезнее написать само состояние. Добавьте в раздел filter следующий самостоятельный пример пояснения:
<p class="lesson-note">
<strong>Обратите внимание:</strong>
если FirstName отсутствует, условие нужно обработать отдельно.
</p>
Название обозначает назначение, а текст объясняет конкретную причину. Цвет фона можно добавить как поддержку оформления, но без него предупреждение остаётся содержательным. Аналогично будущая ошибка формы должна назвать поле и способ исправления, а не ограничиться красной рамкой. Подробное поведение сообщений рассмотрим в соответствующем уроке.
Не нужно обозначать любую необычную ситуацию как «Ошибка». Ограничение метода, дополнительный вариант и результат отправки имеют разные значения. Если всё окрашено одинаково и снабжено одинаковой меткой, читатель перестаёт различать важность. Текстовые названия помогают сохранить эти различия независимо от палитры.
Границы и состояния управления
Для значимых графических частей и компонентов применяется отдельный критерий Non-text Contrast. В предусмотренных им случаях отношение к соседним цветам должно быть не менее 3:1. Это не универсальное требование ко всем декоративным разделителям: сначала определяется, нужна ли графическая часть для распознавания компонента или смысла.
У поля может быть достаточная граница в обычном состоянии и почти невидимая в состоянии ошибки. У кнопки текст может оставаться читаемым, а выбранное состояние — передаваться только сменой фона. Поэтому реестр цветовых пар должен учитывать состояния: обычное, фокус, выбор, ошибка и другие действительно существующие варианты. Отдельный набор красивых образцов палитры не показывает их использование.
В техническом уроке проверьте также комментарии и второстепенные части листинга. Они могут выглядеть как необязательные украшения, хотя объясняют условие выполнения программы. Название «второстепенный текст» не означает отсутствие учебного смысла. Если цвет делает комментарий почти незаметным, сначала уточните его роль, а затем выберите читаемое сочетание, сохранив различие между кодом и пояснением.
Результат урока — способ оценивать конкретную пару и оформление, в котором ссылка и предупреждение имеют признаки помимо цвета. Для следующей редакционной сверки выпишите элементы стенда с их назначением, фоном и состоянием. После этого можно рассматривать увеличение и перестроение: достаточный контраст не поможет тексту, который обрезан фиксированной высотой контейнера.