Стили

Qwik не навязывает подход к стилизации, вы можете стилизовать своё приложение Qwik, используя любой метод, который вы предпочитаете, например, CSS, CSS-in-JS, модули CSS...

CSS-модули

Благодаря Vite, Qwik из коробки поддерживает CSS-модули.

Чтобы использовать модули CSS, просто создайте файл .module.css. Например, MyComponent.module.css и импортируйте его в свой компонент.

src/components/MyComponent/MyComponent.module.css
.container {
  background-color: red;
}

Затем импортируйте модуль CSS в свой компонент:

src/components/MyComponent/MyComponent.tsx
import { component$ } from '@builder.io/qwik';
import styles from './MyComponent.module.css';
 
export default component$(() => {
  return <div class={styles.container}>Привет, мир</div>;
});

Помните, что Qwik использует class вместо className для CSS-классов.

Для назначения нескольких классов qwik также принимает массивы, объекты и их смесь:

src/components/MyComponent/MyComponent.tsx
import { component$ } from '@builder.io/qwik';
import styles from './MyComponent.module.css';
 
export default component$((props) => {
  // Пример синтаксиса с передачей массива
  return <div class={[
    styles.container,
    'p-8',
    props.isHighAttention ? 'text-green-500' : 'text-slate-500',
    { active: true}
  ]}>Привет, мир!</div>;
 
  // Пример синтаксиса с передачей объекта
  return <div class={{
    'text-green-500': props.isHighAttention,
    'p-4': true
  }}>Привет, мир!</div>;
});

Глобальные стили

Многие приложения используют глобальные стили для выполнения сброса стилей браузера и/или определения глобальных стилей. Это нормальная практика, но её не рекомендуется использовать для стилизации компонентов. Qwik оптимизирован для того, чтобы браузер загружал только те стили, которые необходимы для текущего представления. Если вы используете глобальные стили, то они будут загружены при первой загрузке, даже если они не нужны на текущей странице.

import './global.css';

Qwik будет автоматически инлайнить этот файл в производственной среде, если объём CSS меньше 10 Кб. Если размер файла превышает 10 Кб, он будет загружен как отдельный файл.

CSS-in-JS

Qwik имеет первоклассную поддержку CSS-in-JS с использованием styled-vanilla-extract, что обеспечивает чрезвычайно эффективное решение css-in-js без какого-либо рантайма!

style.css.ts
import { style } from 'styled-vanilla-extract/qwik';
 
export const blueClass = style({
  display: 'block',
  width: '100%',
  height: '500px',
  background: 'blue',
});
component.tsx
import { component$ } from '@builder.io/qwik';
import { blueClass } from './styles.css';
 
export const Cmp = component$(() => {
  return <div class={blueClass} />;
});
npm run qwik add styled-vanilla-extract

Пожалуйста, обратитесь к документации для получения дополнительной информации.

Как насчет emotion или других CSS-in-JS библиотек? Несмотря на чрезвычайную популярность, emotion и другие CSS-in-JS библиотеки не являются лучшим выбором для Qwik. Они не оптимизированы по производительности во время выполнения и не имеют хорошей поддержки потоковой передачи SSR, что приводит к снижению производительности сервера и клиента.

Styled-components

Стилизованные компоненты - это популярный в стране React инструмент для написания CSS-в-JS. Благодаря тому же плагину styled-vanilla-extract, вы можете писать стили с синтаксисом styled-components в Qwik с нулевыми затратами времени!

npm run qwik add styled-vanilla-extract

Например:

styles.css.ts
import { styled } from 'styled-vanilla-extract/qwik';
 
export const BlueBox = styled.div`
  display: block;
  width: 100%;
  height: 500px;
  background: blue;
`;
component.tsx
import { component$ } from '@builder.io/qwik';
import { BlueBox } from './styles.css';
 
export const Cmp = component$(() => {
  return <BlueBox />;
});

Локальные стили

Чтобы использовать локальные стили CSS, вы можете воспользоваться хуком useStylesScoped$(), экспортированным из @builder.io/qwik.

src/components/MyComponent/MyComponent.tsx
import { component$, useStylesScoped$ } from '@builder.io/qwik';
 
export default component$(() => {
  useStylesScoped$(`
    .container {
      background-color: red;
    }
  `);
  return <div class="container">Привет, мир</div>;
});

Вы также можете импортировать внешний файл CSS. Для этого необходимо добавить параметр запроса ?inline к импорту CSS-файла и передать экспорт CSS-файла по умолчанию в хук useStyleScoped$().

src/components/MyComponent/MyComponent.css
.container {
  background-color: red;
}
src/components/MyComponent/MyComponent.tsx
import { component$, useStylesScoped$ } from '@builder.io/qwik';
 
import styles from './MyComponent.css?inline';
 
export default component$(() => {
  useStylesScoped$(styles);
  return <div class="container">Hello world</div>;
});

Селектор :global()

При использовании useStylesScoped$ все дочерние селекторы в наборе правил будут привязаны к компоненту. Если вам нужно стилизовать дочерние компоненты, отображаемые через <Slot />, вам нужно выйти за пределы области стилей текущего компонента с помощью селектора :global().

import { useStylesScoped$, component$ } from '@builder.io/qwik';
 
export const List = component$(() => {
  useStylesScoped$(`
    .list {
      display: flex;
 
      > :global(*nth-child(3)) {
        width: 100%
      }
    }
  `);
 
  return (
    <div class="list">
      <Slot />
    </div>;
  );
});

Это приведёт к рендеру css-селектора .list.⭐️8vzca0-0 > *:nth-child(3), который позволит вам стилизовать дочерние компоненты. Это можно считать эквивалентом использования ::ng-deep в Angular.

Помните, что это может привести к непредвиденным последствиям, которые будут распространяться вниз по дереву компонентов.

useStyles$()

Это лениво-загружаемая ссылка на стили компонента.

Стили компонентов позволяют Qwik лениво загружать информацию о стиле для компонента только тогда, когда это необходимо (и избегать двойной загрузки в случае гидратации SSR).

import { useStyles$, component$ } from '@builder.io/qwik';
import styles from './code-block.css?inline';
 
export const CmpStyles = component$(() => {
  useStyles$(styles);
  return <span class="my-text">Какой-то текст</span>;
});
// code-block.css
.my-text {
  color: red;
}

Обратите внимание, что для импорта CSS как строки в Vite, вам нужно добавить параметр запроса ?inline к импорту, вот так: import styles from './code-block.css?inline';

CSS препроцессоры

Благодаря Vite, Qwik поддерживает такие препроцессоры CSS, как Sass, Less, Stylus и PostCSS.

Для них не нужно устанавливать специфические для Qwik плагины, но соответствующий препроцессор должен быть установлен:

# .scss и .sass
npm add -D sass
 
# .less
npm add -D less
 
# .styl и .stylus
npm add -D stylus

Дополнительную информацию можно найти в Vite's docs.

Tailwind

Чтобы использовать в своём приложении Tailwind, добавьте его с помощью нашей встроенной интеграции:

npm run qwik add tailwind

Более подробную информацию можно найти в документации по интеграции.

PostCSS

Чтобы использовать в своём приложении PostCSS, добавьте его с помощью нашей встроенной интеграции:

npm run qwik add postcss

Важно: Поскольку мы используем Vite, рабочая конфигурация должна выглядеть следующим образом:

// Configuration with vite
module.exports = {
  plugins: {
    autoprefixer: {},
    "postcss-preset-env": {
      stage: 3,
      features: {
        "nesting-rules": true,
      },
    },
  },
}

Теперь вы можете использовать CSS с вложенными правилами, подобными следующим:

body {
  & .box {
    background: red;
 
    &:hover {
      background: yellow;
    }
  }
}

Более подробную информацию можно найти в документации по интеграции.

Почему не встроить стили с помощью тега <style>?

Простой способ убедиться, что в компонент загружены правильные стили, заключается в том, чтобы встроить информацию о стилях в компонент следующим образом:

export const MyComponent = () => {
  return (
    <>
      <style>.my-class { color: red; }</style>
      Мой компонент
    </>
  );
}

Проблема этого подхода заключается в том, что мы будем загружать стили дважды.

  1. Стили вставляются в HTML как часть SSR.
  2. Затем, когда компонент становится недействительным и его нужно перерисовать, стили загружаются снова, поскольку они встроены.

Необходимо загрузить стили независимо от компонента. Для этого и существует useStyles$(). Существует два сценария:

  1. Компонент рендерится на сервере, а стили вставляются в <head> как часть SSR.
  • Добавление нового экземпляра компонента в приложение не требует загрузки стилей, так как они уже включены в SSR.
  1. Компонент впервые отображается на клиенте. В этом случае новый компонент не будет иметь стилей в <head>, так как компонент не был частью SSR.
  • Добавление нового компонента, который не был частью SSR, требует загрузки и вставки стилей в <head>.

Участники

Спасибо всем участникам, которые помогли сделать эту документацию лучше!

  • manucorporat
  • zanettin
  • cunzaizhuyi
  • manuelsanchez2
  • literalpie
  • forresst
  • DustinJSilk
  • saikatdas0790
  • LiKang6688
  • Craiqser
  • adamdbradley
  • the-r3aper7
  • mhevery
  • igorbabko
  • mrhoodz
  • tanftw