12. Стилизация
Qwik поддерживает несколько подходов к стилизации: встроенные CSS, CSS Modules, глобальные стили, Tailwind CSS и Vanilla Extract. Каждый подход имеет свои плюсы.
Встроенные стили с useStylesScoped$
Заголовок раздела «Встроенные стили с useStylesScoped$»useStylesScoped$ добавляет изолированные CSS стили к компоненту — они применяются только к данному компоненту и его дочерним элементам:
import { component$, useStylesScoped$ } from '@builder.io/qwik';
export const Card = component$(() => { useStylesScoped$(\` .card { background: #1e293b; border-radius: 12px; padding: 20px; }
h2 { color: #ac7ef4; /* Только h2 внутри этого компонента! */ } \`);
return ( <div class="card"> <h2>Заголовок карточки</h2> <p>Контент</p> </div> );});Qwik автоматически добавляет уникальный атрибут для изоляции:
<div class="card ⭐sx2a3c"> <!-- Уникальный суффикс --> <h2>Заголовок карточки</h2></div>Глобальные стили с useStyles$
Заголовок раздела «Глобальные стили с useStyles$»import { component$, useStyles$ } from '@builder.io/qwik';
export const GlobalLayout = component$(() => { useStyles$(\` :root { --primary: #ac7ef4; --bg: #0f172a; }
* { box-sizing: border-box; } body { background: var(--bg); } \`);
return <slot />;});CSS Modules
Заголовок раздела «CSS Modules»Qwik поддерживает CSS Modules из коробки:
.button { background: #ac7ef4; color: #0f172a; border: none; border-radius: 8px; padding: 10px 20px;}
.button.secondary { background: transparent; color: #ac7ef4; border: 1px solid #ac7ef4;}import { component$ } from '@builder.io/qwik';import styles from './Button.module.css';
export const Button = component$<{ variant?: 'primary' | 'secondary' }>((props) => { return ( <button class={[styles.button, props.variant === 'secondary' && styles.secondary]}> Click me </button> );});Tailwind CSS
Заголовок раздела «Tailwind CSS»Tailwind — популярный выбор для Qwik приложений:
npm run qwik add tailwindПосле добавления Tailwind классы работают как обычно:
export const HeroSection = component$(() => { return ( <section class="min-h-screen bg-slate-950 flex items-center justify-center"> <div class="text-center"> <h1 class="text-5xl font-bold text-purple-400 mb-4"> ⚡ Qwik </h1> <p class="text-slate-400 text-lg"> Resumable, O(1) загрузка </p> </div> </section> );});Динамические классы
Заголовок раздела «Динамические классы»// Объект классов<div class={{ 'btn': true, 'btn-primary': variant === 'primary', 'btn-disabled': isDisabled,}}>
// Массив<div class={['btn', isActive && 'btn-active', extraClass]}>
// Строка шаблона<div class={\`btn btn--\${variant}\`}>CSS-переменные с useSignal
Заголовок раздела «CSS-переменные с useSignal»export const ThemeButton = component$(() => { const hue = useSignal(270); // Фиолетовый (Qwik purple)
return ( <div style={{ '--primary-hue': hue.value + 'deg' }}> <input type="range" min={0} max={360} value={hue.value} onInput$={(_, el) => hue.value = +el.value} /> <button style={{ background: 'hsl(var(--primary-hue), 70%, 70%)' }}> Кнопка с динамическим цветом </button> </div> );});