はじめに
いつもお世話になっております、Tonosakiと申します。
業務や個人開発など普段からNext.js(React)に触れておりますが、UIライブラリやCSSフレームワーク等のスタイリングの選択肢が多く、日々迷うことがあります。
私と同様に、スタイリングのベストプラクティスに悩んでいる方も多いかと思いますので、少しでも皆さんのお役に立てればと思い、今回は、最近注目しているPandaCSS について解説していこうと思います。ᕦ(ò_óˇ)ᕤ
PandaCSSとは
PandaCSSとはChakra UIの開発元によって作られたゼロランタイムCSS in JSライブラリになります。→公式ドキュメント
CSS in JSとは何ぞや
CSS in JSとはJavaScriptのコード内にスタイルを書き込む手法で、外部のCSSファイルに依存することなく、コンポーネント単位でスタイリングをすることで動的なスタイリングを行います。
ゼロランタイムとは何ぞや
従来のランタイムなCSS in JSでは、コンポーネントがレンダリングされるたびにスタイルが再生成されるため、パフォーマンスの低下やオーバーヘッドが発生します。
一方、ゼロランタイムなCSS in JSでは、スタイルをビルド時に生成するため、レンダリングや実行時に不要なスタイルを生成することがありません。これにより、パフォーマンスの低下やオーバーヘッドが防がれ、ページの読み込みが速くなります。
また、不要なスタイルが生成されないため、最終的なCSSファイルのサイズも小さく抑えられます。
React Server ComponentsではランタイムなCSS in JSが非推奨になりつつあるので今までStyled ComponentsやEmotionなどのランタイムなCSS in JSしか使ったことない方はこれを機にPandaCSSを試してみるのも良いかもしれません。
導入
今回はNext.jsでの導入となります。VueやRemixなどの他のJSフレームワークに導入したい場合は以下参照下さい。
→Next.js以外での導入はこちら
インストール、設定
pnpm
pnpm install -D @pandacss/dev
postcss.config.js
ファイル作成
pnpm panda init --postcss
npm
npm install -D @pandacss/dev
postcss.config.js
ファイル作成
npx panda init --postcss
yarn
yarn add -D @pandacss/dev
postcss.config.js
ファイル作成
yarn panda init --postcss
bun
bun add -D @pandacss/dev
postcss.config.js
ファイル作成
bun panda init --postcss
インストール後package.json
ファイルに以下追加
"scripts": {
"prepare": "panda codegen",
}
Gitを使用している場合、自動生成されたstyled-system
フォルダは管理対象外とするため.gitignore
ファイルに以下を追加
styled-system
src/app/globals.css
の全ての内容を以下コードに置き換え
@layer reset, base, tokens, recipes, utilities;
実装
PandaCSSの実装方法は従来のスタイリングとあまり変わりありません。
以下のようにcss({})
でクラス内に直接スタイリングを記述することもできれば、あらかじめ変数に格納してクラスに指定する方法もあります。
import { css } from '../../styled-system/css';
export default function Home() {
return (
<div
className={css({
fontSize: "10px",
color: "black",
padding: "10px 20px",
})}
>
hello world!
</div>
);
}
import { css } from '../../styled-system/css';
export default function Home() {
const style = css({
fontSize: "10px",
color: "black",
padding: "10px 20px",
});
return (
<div className={style}>
hello world!
</div>
);
}
レスポンシブ対応
レスポンシブ対応は以下のようにpanda.config.ts
でブレークポイントを設定することで簡単に実装できます。
export const definePandaConfig({
theme: {
breakpoints: {
sm: '640px', // スマートフォン向け
md: '768px', // タブレット向け
lg: '1024px', // デスクトップ向け
xl: '1280px', // 大きいデスクトップ向け
},
},
})
設定したブレークポイントでスタイリングを指定する場合は以下のように記述します。
export default function Home() {
return (
<div
className={css({
margin: "20px",
fontSize: "30px",
sm: {
margin: "5px",
fontSize: "10px",
},
})}
>
hello world!
</div>
);
}
疑似要素
ホバーなどで使う疑似要素に関しては以下のように記述します。
export default function Home() {
return (
<button
type="button"
className={css({
bg: "black",
color: "white",
_hover: {
bg: "gray",
color: "black",
})}
onClick={}
>
Click!
</button>
);
}
_hover
の他にも_focus
や_before
も同じ形式で記述できます。
レシピ
レシピはスタイリングのパターンや構造を再利用可能な形で定義し、動的なスタイルや状態に応じたスタイリングの再利用を促進するために使用されます。
レシピは以下の4つのプロパティから構成されます。
-
base
:基本スタイル -
variants
:スタイルを異なるバリエーションに分けるために使う -
compoundVariants
:複数のバリアントを組み合わせて、特定の条件下でのみ適用されるスタイルを定義するために使用 -
defaultVariants
:初期状態として適用されるバリアント値を指定するために使用
以下ではレシピの定義し、コンポーネントでプロパティを渡してスタイリングをしています。
({ color: 'cream', size: 'lg' })
の組み合わせに応じてスタイルを動的に生成しています。
compoundVariants
を使うことで特定の組み合わせに対して追加のスタイルを適用させます。
defaultVariants
でデフォルトのスタイル設定を定義できます。
import { cva } from '../styled-system/css'
const button = cva({
base: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
borderRadius: '4px',
fontWeight: 'bold',
},
variants: {
color: {
cream: { bg: '#FFE4DB', color: '#DF4D20' },
orange: { bg: '#DF4D20', color: '#ffffff' },
},
size: {
lg: { fontSize: '24px', padding: '8px' },
sm: { fontSize: '12px', padding: '4px' },
},
},
// 複数のバリアントの組み合わせによるスタイルの適用
compoundVariants: [
{
color: 'orange',
size: 'lg',
css: {
borderRadius: '8px',
},
},
],
// デフォルトのバリアント設定
defaultVariants: {
color: 'cream',
size: 'sm',
},
});
export default function Button() {
return (
<button className={button({ color: 'cream', size: 'lg' })}>
Click!
</button>
)
}
※注意点
Next.jsでは、PandaCSSで生成されたスタイルがキャッシュされることがあります。その際は、以下のコマンドで.next
フォルダを削除し、開発サーバーを再起動することで解決できます。
rm -rf .next
npm run dev
また、package.json
に以下記述で各ビルド前に.next
フォルダを削除することもできます。
"scripts": {
- "dev": "next dev",
+ "dev": "rm -rf .next && next dev",
}
最後に
ここまで読んでいただきありがとうございます( っ- ‸ -c)
PandaCSSはここ1、2年で開発された比較的新しい技術なので、初めて耳にする方も多いかと思います。個人的にはTailwindCSSと同じくらい、開発体験が優れており、パフォーマンスにも申し分ないと感じています。
ここ数年のweb業界は技術の進歩や、入れ替わりが激しく、様々なフレームワークやライブラリであふれかえってます。
時には流行に乗り遅れた気がして焦ることもありますが、その分、開発体験を大きく向上させる技術も増えています。生成AIの助けを借りることで、キャッチアップも早くなり、開発の効率も格段にアップしました。
これからもどんどん進化する技術を楽しみながら、より良いアプリケーションを作っていきたいと思います!