Переменные CSS

Haunted — это библиотека для создания веб-компонентов с использованием реактивного подхода, основанного на хуках, аналогичных React. Важным инструментом для стилизации компонентов является интеграция CSS-переменных, которая позволяет управлять внешним видом элементов динамически и реактивно.


Определение и использование CSS-переменных

CSS-переменные (также называемые кастомными свойствами) задаются через синтаксис --имя-переменной и используются через функцию var(--имя-переменной). В контексте Haunted переменные можно определять как на уровне компонента, так и глобально.

Пример локального определения переменной в компоненте Haunted:

import { html, component } from 'haunted';

function MyButton({ color }) {
  return html`
    <style>
      :host {
        --button-bg: ${color || 'blue'};
        display: inline-block;
        padding: 0.5em 1em;
        background-color: var(--button-bg);
        color: white;
        border-radius: 4px;
        cursor: pointer;
      }
    </style>
    <button>Click Me</button>
  `;
}

customElements.define('my-button', component(MyButton));

Ключевой момент: использование :host позволяет задавать переменные именно для текущего веб-компонента, изолируя их от глобального пространства.


Динамическое изменение переменных

Одним из преимуществ Haunted является реактивность, которая распространяется и на CSS-переменные. Переменные можно изменять через свойства компонента, что позволяет динамически менять стили без перерисовки всего компонента.

Пример изменения цвета кнопки при смене пропса:

function MyButton({ color }) {
  return html`
    <style>
      :host {
        --button-bg: ${color};
      }
      button {
        background-color: var(--button-bg);
        color: white;
        padding: 0.5em 1em;
        border-radius: 4px;
        border: none;
        cursor: pointer;
      }
    </style>
    <button>Dynamic Button</button>
  `;
}

При изменении свойства color Haunted автоматически пересчитает шаблон, и новая переменная будет применена к стилю кнопки.


Наследование и каскадирование

CSS-переменные наследуются по DOM, что позволяет создавать сложные темы и схемы стилизации. В Haunted можно использовать переменные, определённые в родительских элементах, и переопределять их в дочерних компонентах.

Пример:

import { html, component } from 'haunted';

function ParentComponent() {
  return html`
    <style>
      :host {
        --primary-color: red;
      }
    </style>
    <child-component></child-component>
  `;
}

function ChildComponent() {
  return html`
    <style>
      :host {
        color: var(--primary-color);
      }
    </style>
    <div>Text with inherited color</div>
  `;
}

customElements.define('parent-component', component(ParentComponent));
customElements.define('child-component', component(ChildComponent));

В этом примере ChildComponent наследует значение переменной --primary-color от родителя. При переопределении в дочернем компоненте можно локально изменить стиль, не затрагивая других компонентов.


Применение CSS-переменных для темизации

Для создания темы можно использовать набор глобальных переменных и динамически менять их значения через Haunted-компоненты или JavaScript. Например, светлая и тёмная темы могут быть реализованы через переключатель переменных на уровне :root:

function setTheme(theme) {
  const root = document.documentElement;
  if (theme === 'dark') {
    root.style.setProperty('--background', '#333');
    root.style.setProperty('--text-color', '#eee');
  } else {
    root.style.setProperty('--background', '#fff');
    root.style.setProperty('--text-color', '#000');
  }
}

Дочерние компоненты используют эти переменные для своих стилей:

function Card() {
  return html`
    <style>
      div {
        background-color: var(--background);
        color: var(--text-color);
        padding: 1em;
        border-radius: 6px;
        box-shadow: 0 2px 6px rgba(0,0,0,0.2);
      }
    </style>
    <div>Card content</div>
  `;
}

Рекомендации по организации переменных

  1. Использовать :host для локальных переменных — обеспечивает изоляцию и предотвращает конфликты.
  2. Создавать глобальные переменные для тем и общих стилей — через :root или отдельный контейнер.
  3. Использовать дефолтные значения через синтаксис var(--var-name, fallback) — для защиты от отсутствующих переменных.
  4. Стараться избегать жесткой привязки к переменным внутри JavaScript — лучше управлять через шаблон и реактивные пропсы.

Интеграция с реактивными хуками Haunted

Haunted позволяет сочетать хуки состояния (useState) с CSS-переменными для создания интерактивных и динамичных интерфейсов. Например, изменение цвета по клику:

import { html, component } from 'haunted';
import { useState } from 'haunted';

function ColorButton() {
  const [color, setColor] = useState('blue');

  return html`
    <style>
      :host {
        --button-bg: ${color};
      }
      button {
        background-color: var(--button-bg);
        color: white;
        padding: 0.5em 1em;
        border: none;
        border-radius: 4px;
      }
    </style>
    <button @click=${() => setColor(color === 'blue' ? 'green' : 'blue')}>
      Toggle Color
    </button>
  `;
}

customElements.define('color-button', component(ColorButton));

Здесь состояние color напрямую влияет на CSS-переменную --button-bg, создавая плавное и реактивное обновление стиля кнопки.


Использование CSS-переменных в Haunted открывает широкие возможности для динамического, модульного и темизированного подхода к стилизации веб-компонентов, позволяя поддерживать чистую архитектуру и максимальную гибкость интерфейсов.