Библиотека Haunted предоставляет декларативный способ построения Web Components с использованием хуков, знакомых по React. Одним из практических аспектов разработки компонентов является корректная работа с цветом и контрастом, особенно в темах и пользовательских интерфейсах, чувствительных к доступности.
Цветовой контраст определяет соотношение яркости переднего плана и фона. Для текстовых элементов это критично, так как недостаточный контраст снижает читабельность и нарушает требования доступности (WCAG). В среде Web Components стиль часто инкапсулирован внутри Shadow DOM, поэтому значение контраста необходимо контролировать непосредственно в компоненте или передавать из внешней темы.
Haunted позволяет использовать хуки для хранения и обновления состояния цвета:
import { component, useState } from 'haunted';
function Colorful() {
const [color, setColor] = useState('#000');
const [background, setBackground] = useState('#fff');
return html`
<div style="color:${color}; background:${background}">
Текст с динамическими цветами
</div>
`;
}
customElements.define('colorful-text', component(Colorful));
При таком подходе цветовые параметры могут поступать через атрибуты или свойства компонента, обновляться при взаимодействии и участвовать в вычислениях контраста.
Контрастный коэффициент может быть вычислен на основе относительной яркости цветов. Основой служит формула WCAG, использующая линейную яркость каждого канала RGB. Типичное решение — вынести вычисление в отдельную функцию, которую затем вызывать внутри рендера или эффекта:
function luminance(r, g, b) {
const a = [r, g, b].map(v => {
v = v / 255;
return v <= 0.03928
? v / 12.92
: Math.pow((v + 0.055) / 1.055, 2.4);
});
return a[0] * 0.2126 + a[1] * 0.7152 + a[2] * 0.0722;
}
function contrast(rgb1, rgb2) {
const lum1 = luminance(...rgb1);
const lum2 = luminance(...rgb2);
const brightest = Math.max(lum1, lum2);
const darkest = Math.min(lum1, lum2);
return (brightest + 0.05) / (darkest + 0.05);
}
Полученное значение можно использовать для выбора подходящей палитры или автоматического изменения цвета текста при смене фона.
Хуки useEffect и useState позволяют
адаптировать цвета в ответ на изменения пропсов или пользовательских
действий. Например, при выборе фона компонент может автоматически
подбирать подходящий текстовый цвет на основе контрастного
коэффициента:
import { component, useState, useEffect } from 'haunted';
function AdaptiveText({ background }) {
const [color, setColor] = useState('#000');
useEffect(() => {
const bg = hexToRgb(background);
const whiteContrast = contrast(bg, [255, 255, 255]);
const blackContrast = contrast(bg, [0, 0, 0]);
setColor(whiteContrast >= blackContrast ? '#fff' : '#000');
}, [background]);
return html`
<span style="color:${color}; background:${background}">
Контрастный текст
</span>
`;
}
customElements.define('adaptive-text', component(AdaptiveText));
Такой прием помогает сохранить читаемость текста при любой комбинации цветов, не нарушая изоляцию стилей внутри Shadow DOM.
В интерфейсах, где присутствует возможность переключения тем, удобно
сочетать Haunted с CSS Custom Properties. Shadow DOM позволяет безопасно
принимать переменные от родителя и применять их внутри компонента. Через
prefers-color-scheme браузер сообщает о предпочтениях
темного или светлого режима, что также может служить триггером для
перестроения палитры.
Соблюдение минимального контраста повышает доступность интерфейсов и делает компоненты пригодными для реального применения. WCAG рекомендует коэффициент не ниже 4.5:1 для обычного текста и 3:1 для крупного. Использование автоматизированных вычислений в Haunted привносит улучшения в UX без увеличения сложности реализации.
Цветовой контраст может быть не только функциональным, но и эстетическим инструментом. За счет хуков можно экспериментировать с темами, трансформациями и анимациями, не теряя контроля над читаемостью. Так достигается гибкое сочетание дизайна и технических требований внутри одного веб-компонента.