CSS in JS を業務で触ったことのない人に向けて社内勉強会をしたときの資料。
CSS in JS を何となく知る2022年3月18日 社内勉強会用資料ZOZOTOWNWEB部 フロントエンド1 菊地 宏之
View Slide
はじめに想定読者● JS フレームワーク(React、Vue.js)を利用して開発したことがある人● これから CSS in JS ライブラリを使う人スライド内で取扱わないこと● 詳細なコードの書き方の説明● CSS設計● イレギュラーケース
アジェンダ● JS フレームワークを採用する理由とは○ 命令的UIと宣言的UI● CSS in JS とは○ メリット・デメリット● まとめ
そもそも JS フレームワーク(React、Vue.js)を採用する理由とは何か
React を始めとする昨今の JS フレームワークには下記のような特徴がある。● 宣言的 UI● データバインディング● コンポーネント化● 仮想 DOM(高効率レンダリング)React や Vue.js が目新しい技術だから利用しているのではなく、これらが持つコンポーネントや宣言的 UI といった特徴に価値を見出しているため、JS フレームワークを採用している。
「命令的 UI」 と 「宣言的 UI」宣言的 UI の誕生以前は、命令的にコードを記述する必要があった。
命令的 UIどのようにして欲しいか定義していくことを「命令的 UI」と言う(HOW)
宣言的 UI何をしたいかを定義していくことを「宣言的 UI」と言う(WHAT)
「命令的 UI」 VS 「宣言的 UI」「命令的 UI が劣っていて、宣言的 UI が優れている」という話ではない。スケールする設計が求められる大規模開発において、宣言的 UI が有用であるという話である[^1]。そのため、寿命の短いLP や小規模なページの実装をする際に宣言的 UI を採用することがオーバースペックになりうるケースも当然ある。____[^1]: 大規模開発において、設計論を当てはめられないと技術的負債が生じてしまう。React hooks や宣言的 UI によって、設計論を当てはめやすくなる。 ↩
CSS in JS とは
CSS in JS とはCSS in JS とは、外部ファイルでスタイルを定義するのではなく、JavaScript を用いて CSS を記述するアプローチのことを指す。
CSS in JS が解決する課題CSS in JS ライブラリは、コンポーネントに属する CSS 定義をバンドルするライブラリである。CSS in JS を利用することで、CSS はコンポーネントに定義され、外部の CSS ファイルに依存することなく、コンポーネント単体で独立して動作させることができるようになる。グローバルな CSS を利用している場合、CSS の定義を変更した際にどこへ影響があるか分かりづらい。CSS in JS を適切に利用すると、あるコンポーネントの CSS 定義を変更しても他のコンポーネントへの影響がなくすことができる。
CSS in JS ではないアプローチこれは JavaScript 上でスタイルを定義しているが、単なるインラインスタイルであるため、CSS in JS とは呼ばれない。
CSS in JS ライブラリ● styled-jsx● Styled Components● Emotion● linaria● vanilla-extractライブラリによって、記法やzero-runtime など特色が異なる。
CSS in JS ライブラリEmotion の使い方
Emotion の使い方Emotion は、以下のような機能を提供している。● グローバルセレクター● ベンタープレフィックスの自動付与● セレクターのネスト● メディアクエリー● キャッシュ● アニメーションの組み込み● CSR(Client-Side Rendering)、SSR(Server-Side Rendering) 対応…などなど。
記法オブジェクトスタイル記法 タグ付きテンプレートリテラル記法Emotion の場合、このような記述でスタイル定義ができる。(他の CSS in JS ライブラリでも同様の記法が多い)
スタイリング方法@emotion/styled : styled-components と同等の記法が使える@emotion/react: css prop を利用した記法オブジェクトスタイル記法とタグ付きテンプレートリテラル記法を用いて定義ができる。
コードサンプル実際のコードは、リポジトリを確認のこと。
CSS in JS を利用するメリット・デメリット
メリット● カプセル化○ CSS定義はコンポーネントと紐づくため、関心の分離が行われる○ ユニークなクラス名が自動生成されるため、定義したスタイルが他のコンポーネントやライブラリに影響を与えないことが担保される(詳細度)● メンテナンス性○ CSS in JS のスコープ機能によって、ユニークなクラス名が自動生成され、スタイル定義は定義した対象のコンポーネントにのみ影響するため、他への影響を気にすることなく CSS を修正できる○ 細かい CSS 設計(セレクタ階層や命名規則の設計)が不要になる● 動的なスタイリング○ CSS の変数や関数よりも、コンテキストに基づいた動的なスタイリングがしやすい
メリット - Reactの提唱する「関心の分離」マークアップとロジックを別々のファイルに書いて人為的に技術を分離するのではなく、React はマークアップとロジックを両方含む疎結合の「コンポーネント」という単位を用いて関心を分離する。
デメリット● 学習コスト○ CSS に慣れていても CSS in JS を使いこなすための学習コストは少なからず存在する● パフォーマンス○ ランタイム上で実行するとパフォーマンス問題はある(zero-runtime なライブラリを利用したり、SSRで事前にスタイルを生成しておけば良い)● 可読性が低い○ 自動生成されるクラス名の可読性が低い(そもそも読むものではない)● 移植が困難○ CSSの定義の移植は、オブジェクトスタイルを利用していると難しい
まとめ
まとめCSS in JS ライブラリを利用する理由は、JSフレームワークが持つ「コンポーネント」や「宣言的UI」を活かしてより良い開発体験を得るためである。CSS in JS ライブラリを利用することはデファクトではないので、プロダクトに合わせた選定は必要。また、CSS も CSS Cascade Layers や CSS Container Queries などの準備が整いつつあり、CSS設計にパラダイムシフトが近いうちにもたらされることが想像できる。ライブラリが担っていた部分を標準仕様がカバーしていく可能性も大いにあるので、効率的な実装をしていくためにも CSS と CSS in JS ライブラリの動向を追っていく必要はある。