Динамические стили

FAST Element — современная библиотека для создания веб-компонентов на основе стандарта Custom Elements, обеспечивающая мощные механизмы реактивности и управления стилями. Одной из ключевых возможностей является работа с динамическими стилями, позволяющая изменять внешний вид компонентов в зависимости от состояния, свойств или контекста.

Определение стилей в FAST Element

Стили в FAST Element задаются с помощью функции css из пакета @microsoft/fast-element. Синтаксис напоминает стандартные CSS-шаблоны:

import { css } from "@microsoft/fast-element";

const buttonStyles = css`
    :host {
        display: inline-block;
        padding: 8px 16px;
        font-size: 16px;
        border-radius: 4px;
        background-color: var(--button-background, #0078d4);
        color: var(--button-color, #ffffff);
        cursor: pointer;
        transition: background-color 0.3s ease;
    }

    :host(:hover) {
        background-color: var(--button-hover-background, #005a9e);
    }
`;

Здесь используется :host для стилизации корневого элемента компонента. Через переменные CSS (var(--имя-переменной)) можно подключать динамическую стилизацию.

Привязка стилей к свойствам компонента

FAST Element позволяет изменять стили на основе реактивных свойств компонента. Для этого свойства объявляются с помощью декоратора @attr или метода FASTElement.define.

import { FASTElement, html, css, attr } from "@microsoft/fast-element";

const dynamicButtonTemplate = html<Button>`
    <button class="${x => x.primary ? 'primary' : 'secondary'}">
        ${x => x.label}
    </button>
`;

const dynamicButtonStyles = css`
    button {
        padding: 8px 16px;
        border-radius: 4px;
        font-size: 16px;
        transition: all 0.3s ease;
    }

    button.primary {
        background-color: #0078d4;
        color: white;
    }

    button.secondary {
        background-color: #e1e1e1;
        color: #333;
    }
`;

export class Button extends FASTElement {
    @attr label = "Кнопка";
    @attr primary = false;
}

Button.define({
    name: "dynamic-button",
    template: dynamicButtonTemplate,
    styles: dynamicButtonStyles
});

С помощью привязки x => x.primary ? 'primary' : 'secondary' класс кнопки изменяется автоматически при изменении свойства primary. Это позволяет динамически менять внешний вид без вмешательства в DOM напрямую.

Реактивные CSS-переменные

Еще один мощный инструмент — CSS-переменные, привязанные к свойствам компонента через styleMap или напрямую через style:

import { FASTElement, html, css, observable } from "@microsoft/fast-element";

const dynamicStyleTemplate = html<MyBox>`
    <div style="--box-color: ${x => x.color}">
        Контент
    </div>
`;

const dynamicStyleCSS = css`
    div {
        width: 100px;
        height: 100px;
        background-color: var(--box-color, gray);
        transition: background-color 0.3s ease;
    }
`;

export class MyBox extends FASTElement {
    @observable color = "red";
}

MyBox.define({
    name: "my-box",
    template: dynamicStyleTemplate,
    styles: dynamicStyleCSS
});

Изменение свойства color автоматически обновляет CSS-переменную --box-color, что позволяет динамически управлять цветом без пересборки стилей.

Условная стилизация через директивы

FAST Element поддерживает директивы шаблонов, которые дают возможность условно применять стили:

import { html, FASTElement, css, when } from "@microsoft/fast-element";

const conditionalTemplate = html<MyCard>`
    <div class="${x => x.highlight ? 'highlighted' : ''}">
        ${x => x.content}
    </div>
`;

const conditionalStyles = css`
    div {
        padding: 16px;
        border-radius: 8px;
        background-color: white;
        transition: all 0.3s ease;
    }

    .highlighted {
        background-color: #ffeb3b;
        box-shadow: 0 0 10px rgba(0,0,0,0.2);
    }
`;

export class MyCard extends FASTElement {
    @attr content = "Карточка";
    @attr highlight = false;
}

MyCard.define({
    name: "my-card",
    template: conditionalTemplate,
    styles: conditionalStyles
});

Директива x => x.highlight ? 'highlighted' : '' обеспечивает динамическое применение класса, что позволяет управлять стилями на лету в зависимости от состояния компонента.

Комбинирование динамических стилей и темизации

FAST Element хорошо интегрируется с глобальными темами, где переменные CSS задаются на уровне корневого документа или родительского компонента. Комбинирование с динамическими свойствами позволяет создавать полностью настраиваемые элементы:

document.documentElement.style.setProperty('--primary-color', '#4caf50');

const themeButtonStyles = css`
    :host {
        background-color: var(--primary-color, blue);
        color: white;
        padding: 10px 20px;
        border-radius: 4px;
    }
`;

При изменении переменной --primary-color все компоненты, использующие её, обновляют внешний вид без дополнительного кода.

Анимации и переходы

Динамические стили можно комбинировать с CSS-переходами и анимациями для плавных визуальных эффектов. Например, при изменении состояния кнопки:

button {
    transition: background-color 0.3s ease, transform 0.2s ease;
}

button:hover {
    transform: scale(1.05);
}

Использование реактивных свойств в сочетании с transition позволяет создавать интерактивные компоненты с минимальной логикой и максимальной отзывчивостью интерфейса.

Итог

Динамические стили в FAST Element строятся на основе:

  • Реактивных свойств компонента (@attr, @observable)
  • CSS-переменных, привязанных к свойствам
  • Условного применения классов и директив шаблона
  • Интеграции с глобальной темизацией и переходами

Эти инструменты позволяют создавать гибкие, настраиваемые и интерактивные веб-компоненты, полностью соответствующие современным стандартам фронтенд-разработки.