Riot.js предоставляет уникальный подход к построению интерфейсов через компоненты, объединяющие структуру, логику и стили в одном месте. Одной из ключевых особенностей является возможность инкапсуляции стилей, что позволяет избежать конфликтов CSS и упрощает поддержку крупных проектов.
Каждый компонент Riot может содержать собственные CSS-правила внутри
блока <style>:
<my-button>
<button>{opts.label}</button>
<style>
button {
background-color: #3498db;
color: white;
border: none;
padding: 10px 20px;
cursor: pointer;
border-radius: 4px;
}
button:hover {
background-color: #2980b9;
}
</style>
</my-button>
CSS, определённый внутри компонента, применяется только к элементам этого компонента. Это достигается за счёт автоматической генерации уникальных атрибутов для каждого компонента, которые Riot добавляет к селекторам.
Riot.js поддерживает два механизма инкапсуляции стилей:
Пример использования Shadow DOM:
<my-card shadow>
<div class="card">
<h2>{opts.title}</h2>
<p>{opts.content}</p>
</div>
<style>
.card {
padding: 20px;
border: 1px solid #ccc;
border-radius: 8px;
background-color: #f9f9f9;
}
h2 {
margin: 0 0 10px;
font-size: 18px;
}
</style>
</my-card>
Атрибут shadow активирует использование Shadow DOM,
изолируя стили компонента полностью от глобального CSS.
Иногда необходимо подключать общие стили, например, переменные CSS или темы. Riot.js позволяет комбинировать локальные и глобальные стили:
<theme-wrapper>
<div class="container">
<my-button label="Click me"></my-button>
</div>
<style>
:global(.container) {
padding: 40px;
background-color: #ecf0f1;
}
</style>
</theme-wrapper>
Использование псевдокласса :global позволяет определять
правила, которые выходят за рамки компонента и применяются к всему
документу.
Стили в Riot.js могут быть динамическими, изменяясь в зависимости от состояния компонента:
<status-indicator>
<span class={stateClass}>{status}</span>
<style>
span {
padding: 5px 10px;
border-radius: 4px;
color: white;
}
.active {
background-color: green;
}
.inactive {
background-color: red;
}
</style>
<script>
export default {
status: 'active',
get stateClass() {
return this.status === 'active' ? 'active' : 'inactive';
}
}
</script>
</status-indicator>
С помощью вычисляемых свойств или реактивных данных можно менять классы и, соответственно, визуальное представление элемента без вмешательства в глобальный CSS.
Riot.js поддерживает использование CSS-переменных для настройки стилей на уровне компонентов:
<color-box>
<div class="box"></div>
<style>
.box {
width: 100px;
height: 100px;
background-color: var(--box-color, #3498db);
}
</style>
<script>
export default {
onMounted() {
this.root.style.setProperty('--box-color', '#e74c3c');
}
}
</script>
</color-box>
Использование CSS-переменных позволяет динамически менять стили компонента без изменения классов и селекторов.
:global.Инкапсуляция стилей в Riot.js обеспечивает чистую архитектуру компонентов, упрощает поддержку и повышает модульность интерфейсов, сочетая гибкость JavaScript и возможности CSS.