0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【CSS-in-JS / vanilla-extract】ゼロランタイム CSS-in-JS の最低限を理解する

0
Posted at

CSS-in-JS とは

CSS のスタイル定義を JavaScript(TypeScript)のコードとして書き、JavaScript に CSS を生成・管理させる仕組みです。

以下の記事で CSS-in-JS について紹介していますので、併せてご覧ください。

ゼロランタイム CSS-in-JS とは

styled-componentsEmotion などの「ランタイム CSS-in-JS」は、コンポーネントがレンダリングされるたびに、JavaScript が CSS を生成してブラウザに挿入します。これは書きやすい反面、レンダリング時に JS の実行コストがかかるというデメリットがありました。

対して、「ゼロランタイム CSS-in-JS」は、このレンダリング時に JS が CSS を生成するという処理そのものをなくします。代わりに、ビルド時にコード内のスタイル定義を静的な .css ファイルへ変換してしまいます。ブラウザが受け取るのは普通の CSS ファイルなので、実行時には CSS-in-JS のための処理が一切走りません。

代表的なライブラリに vanilla-extractPanda CSSStyleX などがあります。

本記事では vanilla-extract を例として紹介します。

vanilla-extract の導入方法

@vanilla-extract/css@vanilla-extract/vite-plugin をインストールします。

npm install --save-dev @vanilla-extract/css @vanilla-extract/vite-plugin

Vite のプラグイン設定に vanillaExtractPlugin を追加します。

// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin'

export default defineConfig({
  plugins: [react(), vanillaExtractPlugin()],
})

vanilla-extract の使い方

■ スタイルを定義する

vanilla-extract では、スタイルを .css.ts という専用の拡張子のファイルに書きます。

// Button.css.ts
import { style } from "@vanilla-extract/css";

export const button = style({
  padding: "8px 16px",
  backgroundColor: "#2563eb",
  color: "#fff",
});

作成したスタイルをコンポーネントから呼び出すには、

import { button } from "./Button.css";

export default function Button() {
  return <button className={button}>Click me!</button>;
}

ビルドを実行してみると、dist/assets/index-68BF59UU.css のような、.css.ts ファイルを元に作られた静的な CSS ファイルが作られます。これを dist/index.html から呼び出しています。

これがビルド時に静的な CSS ファイルを生成する「ゼロランタイム CSS-in-JS」の挙動です。

■ 動的スタイルを定義する

ビルド時に静的 CSS へ変換される都合上、以下の Emotion(ランタイム CSS-in-JS)の例のように「実行時にしか分からない値」をスタイル定義の中に直接書くことができません。

// Emotion
const StyledText = styled.p`
  color: ${(props) => props.color};
`;

vanilla-extract(ゼロランタイム CSS-in-JS)では、CSS 変数を経由して値を渡すのが基本パターンです。

まず .css.ts 側で、createVar を使って値を後から差し込むための CSS 変数を宣言します。

// Button.css.ts
import { createVar, style } from "@vanilla-extract/css";

export const colorVar = createVar();

export const button = style({
  color: colorVar,
});

コンポーネント側では @vanilla-extract/dynamic パッケージの assignInlineVars を使って、実行時の値を CSS 変数へ割り当てます。

npm install @vanilla-extract/dynamic
import { assignInlineVars } from "@vanilla-extract/dynamic";
import { button, colorVar } from "./Button.css";

export default function Button({ color }: { color: string }) {
  return (
    <button
      className={button}
      style={assignInlineVars({
        [colorVar]: color,
      })}
    >
      Click me!
    </button>
  );
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?