スタイル

Qwikは特定のスタイリングアプローチを強制しません。CSS、CSS-in-JS、CSSモジュールなど、好みの方法でQwikアプリをスタイリングできます。

CSSモジュール

Qwikは、CSS ModulesViteのおかげで、すぐに使用できます。

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}>Hello world</div>;
});

QwikはCSSクラスにclassNameではなくclassを使用することに注意してください。

Qwikは、複数のクラスを割り当てるために、配列、オブジェクト、またはそれらの組み合わせも受け入れます。

src/components/MyComponent/MyComponent.tsx
import { component$ } from '@builder.io/qwik';
import styles from './MyComponent.module.css';
 
export default component$((props) => {
  // Array syntax example
  return <div class={[
    styles.container, 
    'p-8', 
    props.isHighAttention ? 'text-green-500' : 'text-slate-500',
    { active: true}
  ]}>Hello world</div>;
 
  // Object syntax example
  return <div class={{  
    'text-green-500': props.isHighAttention,
    'p-4': true
  }}>Hello world</div>;
});

グローバルスタイル

多くのアプリでは、ブラウザのリセットやグローバルスタイルの定義にグローバルスタイルシートを使用しています。これは良い慣習ですが、コンポーネントのスタイリングに使用することは推奨されていません。Qwikは、現在のビューに必要なスタイルをブラウザがダウンロードするように最適化されています。グローバルスタイルシートを使用すると、現在のビューに必要ない場合でも、すべてのスタイルが最初のロード時にダウンロードされます。

import './global.css';

Qwikは、CSSの量が10KB未満の場合、自動的に本番モードでこのファイルをインライン化しようとします。ファイルが10KBを超える場合は、別のファイルとしてロードされます。

CSS-in-JS

Qwikは、styled-vanilla-extractを使用して、非常に効率的なCSS-in-JSソリューションをランタイムなしで実現する、ファーストクラスの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

styled-componentsライブラリは、Reactの世界でCSS-in-JSを記述するための一般的なツールです。同じstyled-vanilla-extractプラグインのおかげで、Qwikでstyled-componentsの構文を使用して、ゼロランタイムコストでスタイルを記述できます!

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

スコープ付きCSSを使用するには、@builder.io/qwikからエクスポートされたuseStylesScoped$()フックを使用できます。

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

外部CSSファイルをインポートすることもできます。そのためには、CSSファイルのインポートに?inlineクエリパラメータを追加し、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>;
  );
});

これにより、.list.⭐️8vzca0-0 > *:nth-child(3)のCSSセレクターがレンダリングされ、子コンポーネントをターゲットにできます。これは、Angularで::ng-deepを使用するのと同等と見なすことができます。

これがコンポーネントツリーに意図しない影響を与える可能性があることに注意してください。

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">Some text</span>;
});
// code-block.css
.my-text {
  color: red;
}

ViteでCSSを文字列としてインポートするには、import styles from './code-block.css?inline';のように、インポートに?inlineクエリパラメータを追加する必要があることに注意してください。

CSSプリプロセッサ

Viteのおかげで、QwikはSass、Less、Stylus、PostCSSなどのCSSプリプロセッサをサポートしています。

これらに対してQwik固有のプラグインをインストールする必要はありませんが、対応するプリプロセッサ自体をインストールする必要があります。

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

詳細については、Viteのドキュメントを確認してください。

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>
      My Component
    </>
  );
}

このアプローチの問題は、スタイルを2回ロードすることです。

  1. スタイルはSSRの一部としてHTMLに挿入されます。
  2. その後、コンポーネントが無効になり、再レンダリングが必要になると、スタイルがインライン化されているため、スタイルが再度ロードされます。

必要なのは、コンポーネントとは独立してスタイルをロードすることです。これがuseStyles$()の目的です。2つのシナリオがあります。

  1. コンポーネントがサーバー上でレンダリングされ、スタイルはSSRの一部として<head>に挿入されます。
    • アプリケーションにコンポーネントの新しいインスタンスを追加しても、スタイルはSSRの一部としてすでに含まれているため、スタイルをロードする必要はありません。
  2. コンポーネントがクライアントで初めてレンダリングされます。その場合、コンポーネントはSSRの一部ではなかったため、新しいコンポーネントには<head>にスタイルがありません。
    • SSRの一部ではなかった新しいコンポーネントを追加するには、スタイルをロードして<head>に挿入する必要があります。

貢献者

このドキュメントを改善するためにご協力いただいたすべての貢献者に感謝します!

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