🎨

Modern Styling in React

2024/03/04に公開

フロンエンド開発にReactを用いるとき様々なスタイリングソリューションがありますよね。今回は素のCSSTailwind CSSCSS-in-JSのどれを使用するかという観点から、それぞれおすすめのスタイリングソリューションをご紹介させていただきます。

素のCSS

まず素のCSSならMantineというコンポーネントライブラリがおすすめです。Mantineはもともと他のコンポーネントライブラリと比較してもコンポーネントの種類がかなり充実してましたが、v7.4.0よりチャート系のコンポーネントも追加されました。現在、チャート系までサポートするコンポーネントライブラリは私の知る限り、Mantineと後述のTremorくらいです。しかし、Tremorはチャート系などの管理画面のコンポーネントは充実しててもその他のコンポーネントが不足しているため、Mantineはユーザー画面と管理画面の開発のどちらにも対応できるという点で優れております。内部的にはどちらのチャート系のコンポーネントもRechartsが使われてます。

さらにMantineにはv7.6.0よりHeadlessMantineProviderというMantineReact Aria Components等のようにヘッドレスUIライブラリ(スタイルを持たず機能のみのUIコンポーネント)として使用できる機能が提供されてます。そのため、今までMantineを使ってみたかったけれど、スタイルが好きじゃなかったという開発者の皆さんにも自らスタイルを適用しご使用いただけます(スタイルを適用するというのは大変ではありますが。。)

https://mantine.dev/

Tailwind CSS

Tailwind CSSならshadcn/uiというコンポーネントライブラリがおすすめです。shadcn/uiRadix UITailwind CSSによって作られており、npmによって管理せず、自らのコードベースで管理するという特徴があります(この特徴をRe-usableといいます)。それにより、カスタマイズがしやすくコンポーネントを頻繁に微調整する場合に使いやすいです。しかし、ビジネスのことを考えると、独自のUIを構築するよりもいち早く機能を実装するためにコンポーネントの種類もより豊富なMantineを使うのも適切です。ただMantineTailwind CSSとは相性が悪いのです。併用できない認識なので、Tailwind CSSを使いたい場合にはshadcn/uiの選択は適切と思われます。

https://ui.shadcn.com/

また、管理画面ならTremorというコンポーネントライブラリがおすすめです。TremorTailwind CSSで管理画面を作るためのコンポーネントライブラリです。datepickerもvisualization(chartなど)もあります。

https://www.tremor.so/

CSS-in-JS

CSS-in-JSならStyleXがおすすめです。StyleXはMeta公式のCSS-in-JS(JS内にスタイルを定義して、コンポーネントに直接適用します)で、今後このStyleX製のコンポーネントライブラリが増えそうです。RSC(React Server Components)の登場によってStyled ComponentsEmotionのようなCSS-in-JSは推奨されませんが、StyleXはゼロランタイムなCSS-in-JSとしてRSC対応しております。

ゼロランタイムなCSS-in-JSライブラリである StyleXRSC と互換性を持つ理由は、StyleXによって生成されるスタイルがビルド時に静的ファイルとして処理され、ランタイムで追加のJavaScript実行を必要としないためです。RSCの主な目的は、サーバーサイドだけでも完結できるものを事前に処理し、クライアントサイドのレンダリング負荷を減らすことにあります。一方で、Styled ComponentsEmotion のような従来のCSS-in-JSライブラリは、クライアントサイドでスタイルを動的に生成し適用するためにJavaScriptの実行を必要としました。これはRSCが目指す方向性と逆行します。しかし、StyleXはビルド時にスタイルを完全に処理し、ランタイムでのJavaScript実行を不要にすることで、RSCとの互換性を実現しています。

https://stylexjs.com/

今回ご紹介させていただいたスタイリングソリューションはいずれも
RSC(React Server Components)に対応しております。
なにか間違ってましたらご指摘いただけますと幸いです!🙏

Discussion