CSS переменные и кастомные свойства

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

Определение и синтаксис CSS переменных

CSS переменные объявляются с использованием префикса -- и могут быть использованы в любом месте стилей через функцию var(). Основной синтаксис:

:root {
  --primary-color: #4CAF50;
  --font-size: 16px;
}

p {
  color: var(--primary-color);
  font-size: var(--font-size);
}

В контексте Lit кастомные свойства позволяют создавать темизируемые компоненты, где стили компонента можно изменять извне без прямого редактирования CSS внутри компонента.

Использование CSS переменных внутри веб-компонентов

Lit поддерживает встроенные стили через шаблон css. Для работы с переменными достаточно определить их внутри стиля компонента:

import { LitElement, html, css } from 'lit';

class MyButton extends LitElement {
  static styles = css`
    :host {
      --button-bg: #6200ea;
      --button-color: #ffffff;
    }

    button {
      background-color: var(--button-bg);
      color: var(--button-color);
      padding: 0.5em 1em;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      font-size: 1rem;
    }
  `;

  render() {
    return html`<button><slot></slot></button>`;
  }
}

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

Здесь :host используется для определения переменных на уровне компонента, что позволяет их изменять снаружи, используя обычные селекторы:

my-button {
  --button-bg: #ff5722;
  --button-color: #000000;
}

Переопределение и наследование переменных

Кастомные свойства наследуются стандартным образом через DOM. Если переменная не определена на уровне компонента, она будет унаследована из родителя или корня документа:

:root {
  --font-color: black;
}

my-button {
  --button-color: var(--font-color);
}

Такой подход обеспечивает гибкую тематизацию без необходимости дублировать стили для каждого компонента.

Использование переменных в динамических стилях Lit

Lit позволяет использовать JavaScript для динамического управления CSS переменными, что особенно полезно при изменении состояния компонента:

this.style.setProperty('--button-bg', this.active ? 'green' : 'gray');

Это позволяет создавать реактивные стили, которые автоматически изменяются при изменении состояния компонента.

Калькуляции и fallback значения

Функция var() поддерживает значения по умолчанию, если переменная не определена:

button {
  background-color: var(--button-bg, blue);
}

Также можно комбинировать переменные с CSS-функциями:

button {
  padding: calc(var(--button-padding, 0.5em) * 2);
}

Это позволяет использовать динамические расчеты и упрощает поддержку адаптивного дизайна.

Совместимость с Shadow DOM

В Lit компоненты по умолчанию используют Shadow DOM. CSS переменные — единственный способ передавать стили внутрь Shadow DOM извне без нарушения инкапсуляции. Любые стили, заданные через обычные селекторы вне компонента, не будут применяться, за исключением кастомных свойств:

/* Применяется внутри Shadow DOM через переменные */
my-button {
  --button-bg: red;
}

Практические рекомендации

  • Использовать переменные для ключевых цветов, размеров и шрифтов, чтобы компоненты легко поддавались кастомизации.
  • Сохранять значения по умолчанию в :host для независимости компонента.
  • Использовать JavaScript для реактивной установки переменных в зависимости от состояния или данных.
  • Минимизировать жесткое задание цветов и размеров внутри внутренних селекторов, отдавая предпочтение переменным.

CSS переменные в Lit становятся мощным инструментом для построения темизируемых и реактивных компонентов, совместимых с Shadow DOM и легко адаптируемых к изменяющемуся дизайну. Они обеспечивают модульность и повторное использование стилей на уровне всей системы компонентов.