Shadow DOM создаёт изолированное дерево элементов внутри веб-компонента, обеспечивая локальный контекст для разметки и стилей. В библиотеке Atomico работа со Shadow DOM является встроенной и естественной частью создания компонентов.
В Atomico стили задаются с помощью функции css из пакета
библиотеки. Это позволяет писать CSS прямо внутри компонента, а
библиотека автоматически внедряет их в Shadow DOM:
import { c, css } from "atomico";
const styles = css`
:host {
display: block;
font-family: sans-serif;
color: #333;
}
button {
background: #007acc;
border: none;
color: white;
padding: 0.5em 1em;
cursor: pointer;
border-radius: 4px;
transition: background 0.3s ease;
}
button:hover {
background: #005fa3;
}
`;
function MyButton() {
return (
<host>
<button>Click me</button>
</host>
);
}
MyButton.styles = styles;
export default c(MyButton);
Ключевые моменты:
:host — селектор, который обращается к корневому
элементу компонента. С его помощью можно задавать базовые стили самого
компонента.Shadow DOM обеспечивает полную инкапсуляцию стилей. Любые CSS-правила, определённые внутри компонента, не воздействуют на внешние элементы, и наоборот.
const inputStyles = css`
input {
border: 1px solid #ccc;
padding: 0.5em;
border-radius: 2px;
outline: none;
transition: border-color 0.2s;
}
input:focus {
border-color: #007acc;
}
`;
function TextInput() {
return (
<host>
<input placeholder="Введите текст" />
</host>
);
}
TextInput.styles = inputStyles;
export default c(TextInput);
Особенности:
::before и ::after работают
только внутри компонента, если определены локально.--variable) позволяет
передавать стили из внешнего контекста внутрь Shadow DOM через
:host.Atomico позволяет сочетать Shadow DOM и CSS-переменные для гибкой кастомизации компонентов:
const cardStyles = css`
:host {
display: block;
padding: var(--card-padding, 1em);
background-color: var(--card-bg, #f9f9f9);
border-radius: var(--card-radius, 8px);
box-shadow: 0 2px 6px rgba(0,0,0,0.1);
}
h2 {
margin: 0 0 0.5em 0;
font-size: 1.2em;
}
p {
margin: 0;
font-size: 0.9em;
}
`;
function Card({ children }) {
return (
<host>
{children}
</host>
);
}
Card.styles = cardStyles;
export default c(Card);
Выводы по CSS-переменным:
Анимации можно задавать напрямую в Shadow DOM, что предотвращает конфликты с глобальными анимациями:
const fadeInStyles = css`
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
:host {
display: block;
animation: fadeIn 0.5s ease-out;
}
`;
function FadeBox() {
return (
<host>
<div>Анимированный блок</div>
</host>
);
}
FadeBox.styles = fadeInStyles;
export default c(FadeBox);
@keyframes) объявленные внутри Shadow
DOM не конфликтуют с глобальными анимациями.Atomico позволяет создавать динамические стили с помощью функции
css и шаблонных литералов:
const buttonStyles = (color) => css`
button {
background: ${color};
border: none;
padding: 0.5em 1em;
color: white;
border-radius: 4px;
cursor: pointer;
}
`;
function ColoredButton({ color }) {
return (
<host>
<button>Нажми меня</button>
</host>
);
}
ColoredButton.styles = (props) => buttonStyles(props.color);
export default c(ColoredButton);
Особенности динамических стилей:
props).Shadow DOM полностью поддерживает медиазапросы, позволяя делать адаптивные компоненты:
const responsiveStyles = css`
:host {
display: block;
padding: 1em;
}
div {
background: #eee;
padding: 1em;
}
@media (max-width: 600px) {
div {
background: #ddd;
}
}
`;
function ResponsiveBox() {
return (
<host>
<div>Контент</div>
</host>
);
}
ResponsiveBox.styles = responsiveStyles;
export default c(ResponsiveBox);
Эти возможности делают Shadow DOM в Atomico мощным инструментом для создания модульных и полностью инкапсулированных компонентов с гибкой стилизацией.