Компоненты в Lit строятся на основе стандартного Web Components API,
расширяя его удобными инструментами для реактивного обновления и
шаблонной разметки. Основой является класс, наследующийся от
LitElement, который предоставляет возможность описывать
состояние компонента через свойства и шаблоны
через функцию render().
import { LitElement, html, css } from 'lit';
class MyComponent extends LitElement {
static properties = {
title: { type: String }
};
static styles = css`
:host {
display: block;
padding: 16px;
box-sizing: border-box;
}
`;
render() {
return html`<h1>${this.title}</h1>`;
}
}
customElements.define('my-component', MyComponent);
Ключевой момент — использование :host в стилях для
управления корневым элементом компонента. Это важно для адаптивной
верстки, чтобы компоненты корректно реагировали на изменения размеров
контейнера.
Для адаптивности критически важно использовать flexbox и CSS Grid. В Lit стили можно определять как глобально для компонента, так и локально.
static styles = css`
:host {
display: block;
padding: 1rem;
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 16px;
}
.item {
background: lightgray;
padding: 16px;
border-radius: 8px;
}
`;
Использование repeat(auto-fit, minmax()) позволяет сетке
автоматически подстраиваться под ширину контейнера, создавая адаптивные
колонки без медиа-запросов.
Lit поддерживает стандартный CSS, поэтому можно применять медиа-запросы для тонкой настройки внешнего вида на разных устройствах:
static styles = css`
:host {
display: block;
}
.container {
display: flex;
flex-direction: row;
}
@media (max-width: 768px) {
.container {
flex-direction: column;
}
}
`;
Применение медиа-запросов внутри компонента гарантирует, что его поведение адаптивно без вмешательства в глобальные стили страницы.
С помощью реактивных свойств можно изменять внутреннее состояние
компонента в зависимости от размеров окна или контейнера. Комбинация
ResizeObserver и реактивных свойств позволяет динамически
адаптировать разметку:
class ResponsiveComponent extends LitElement {
static properties = {
smallScreen: { type: Boolean }
};
constructor() {
super();
this.smallScreen = false;
this._resizeObserver = new ResizeObserver(entries => {
for (let entry of entries) {
this.smallScreen = entry.contentRect.width < 600;
}
});
}
connectedCallback() {
super.connectedCallback();
this._resizeObserver.observe(this);
}
disconnectedCallback() {
this._resizeObserver.disconnect();
super.disconnectedCallback();
}
render() {
return html`
<div class="${this.smallScreen ? 'vertical' : 'horizontal'}">
<slot></slot>
</div>
`;
}
}
Такой подход позволяет изменять структуру компонента без перезагрузки страницы, делая его полностью адаптивным.
Для текста и элементов интерфейса удобно использовать единицы
rem и vw вместо фиксированных px.
Это обеспечивает масштабирование компонентов в зависимости от
размера контейнера и экрана:
static styles = css`
h1 {
font-size: 2rem;
}
p {
font-size: 1rem;
}
@media (max-width: 600px) {
h1 {
font-size: 5vw;
}
p {
font-size: 3vw;
}
}
`;
Использование vw в сочетании с rem
позволяет сохранять читаемость текста на любых устройствах.
Локальные стили компонентов защищают их от глобальных конфликтов. Для изменения внешнего вида компонента на разных экранах можно использовать CSS-переменные:
static styles = css`
:host {
--padding: 16px;
display: block;
padding: var(--padding);
}
@media (max-width: 768px) {
:host {
--padding: 8px;
}
}
`;
Комбинация CSS-переменных и медиа-запросов обеспечивает гибкость и удобство в поддержке адаптивного дизайна.
Lit позволяет управлять классами через выражения внутри шаблона. Это упрощает создание адаптивных интерфейсов без дублирования CSS:
render() {
const classes = {
horizontal: !this.smallScreen,
vertical: this.smallScreen
};
return html`<div class="${Object.keys(classes).filter(k => classes[k]).join(' ')}">
<slot></slot>
</div>`;
}
Такой подход уменьшает зависимость от медиа-запросов, позволяя изменять стили в зависимости от состояния компонента.
Для сложных интерфейсов можно использовать сторонние CSS-фреймворки (например, Tailwind или Bootstrap) внутри Lit-компонентов. Важно обернуть сторонние классы внутри локальных контейнеров, чтобы сохранить инкапсуляцию стилей:
render() {
return html`
<div class="wrapper">
<button class="btn btn-primary">Кнопка</button>
</div>
`;
}
Стили будут применяться только внутри wrapper, не
затрагивая другие элементы страницы.
Адаптивная верстка в Lit строится на сочетании CSS-сеток, медиа-запросов, реактивных свойств и инкапсуляции стилей. Такой подход позволяет создавать компоненты, которые динамически реагируют на размеры экрана и контейнера, оставаясь независимыми от глобальной страницы и обеспечивая удобство поддержки и расширения интерфейса.