Site cover image

Site icon image MEGUMI SHIMABUKURO

This blog is all about things I've tried and found out.

📚 Tailwind CSS 実践入門 を読んだ感想

はじめに

普段 Tailwind CSS を使って開発してるのですが、提供されてるクラスを使ってるだけといった感じの理解度なので、ちゃんと勉強しようと思いこの本を手に取ってみました。

ユーティリティーファーストとは何か、Tailwind CSS の思想、さらにコンポーネントやデザインシステムをどう作っていくかなどにも言及されていて、普段なんとなく Tailwind CSS を使ってる僕にとって刺さる内容でした。

特に 1章、6章、7章、9章が おすすめで、Tailwind CSS のお気持ち、ユーティリティファーストのことを少しわかるようになった気がします。

Tailwind CSS を使っているけど、もう少し詳しく知りたい人やこれから使いたいという人におすすめの一冊です。

第1章 ユーティリティファーストとは何か

第2章 Tailwind CSSはどういうフレームワークか

第3章 Tailwind CSSを導入する

第4章 Tailwind CSSでマークアップする

第5章 Tailwind CSSの背後にあるコンセプトを理解する

第6章 Tailwind CSSでコンポーネントを設計する

第7章 Tailwind CSSをカスタマイズする

第8章 Tailwind CSSを既存のプロジェクトに導入する

第9章 ユーティリティファーストでデザインシステムを構築する

以下、章ごとのメモ書きと感想です。

第1章 ユーティリティファーストとは何か

📝 この章に書いてあること
  • ユーティリティファーストとは何か書かれてる
    • ユーティリティーファーストとは
      • あらかじめ決められた値に対するユーティリティクラスを利用するアプローチ
        • 一見、単なるインラインスタイルと同じに見えるが、色や文字サイズには任意の値を入れていいわけではなく、Tailwind CSS で定義されたユーティリティクラスに従ってスタイリングする制約がある
          • つまり、あらかじめ定義されたデザインシステムに従ったスタイリングになると言える
        • 最初はユーティリティだけで作り、その後スタイルを抽象化して、コンポーネントのスタイルを定義する
      • ユーティリティファーストの対局にあるのがセマンティックなアプローチ
        • これまではセマンティックなアプローチだった
        • セマンティックなアプローチとは、意味のある単位で CSS のクラス名を定義するようなアプローチ
  • ユーティリティファーストのメリット
    • クラス名を考える必要がない
    • HTMLとCSSを交互に見る必要がない
    • 影響範囲が明確
  • ユーティリティファーストの思想
    • まずはユーティリティクラスだけで表現してみて、あくまでも必要に応じて抽象化すること
    • 基本的には全てをユーティリティで書く
  • UIデザインの自由度は一貫性のなさとトレードオフの関係である

💁🏻‍♂️ 感想

Tailwind CSS は自由にスタイリングできる印象があったが、ユーティリティクラスにあるクラスだけを使う制約があり、この制約によってデザインのルールに則ってスタイリングができる、という考え方みたい。この考え方はこれまで意識してなかったので、学べてよかった。

前の世代のCSSの設計の歴史を振り返りながら、なぜユーティリティファーストが良いのか、解説されててわかりやすくてよかった。

第2章 Tailwind CSSはどういうフレームワークか

📝 この章に書いてあること
  • Tailwind CSS がどんなフレームワークなのか書かれてる
    • どんなフレームワークなのか?
      • Tailwind CSS は、テーマに基づく制約をユーティリティクラスで表現してる
      • Tailwind CSS は、静的なCSSを必要なクラス分だけ出力する
      • Tailwind CSS は、最初はユーティリティだけで作り、後からスタイルを抽象化するという考え方を推奨してる
  • Tailwind CSS が提供していること
    • ユーティリティを静的なCSSで提供する
    • ユーティリティがメインのクラス
      • 従来の CSS フレームワークでは、UI部品(コンポーネント)のクラスがメインにあり、そこから外れた場合ユーティリティクラスを使う
      • この発想の逆で、ユーティリティクラスがメインにあり、そこからUI部品の抽象化したクラスを抽出する
        • ユーティリティーファーストと言われる所以
    • カスタマイズすることを念願に置かれてるフレームワーク
      • デザインシステムを構築したい開発組織にとって便利なフレームワーク
        • Tailwind の公式サイトでも API for your design system と謳ってる
    • バンドルサイズを抑える工夫がある
  • Tailwind CSS が提供していないこと
    • 便利なUIコンポーネントを提供しない
      • Tailwind CSS で提供されるのはテーマから導出されるクラス群なので、それを超えた抽象化した再利用可能なUIの部品は利用者側で考えるべき

💁🏻‍♂️ 感想

ユーティリティクラスがメインにあり、そこから抽象化してUI部品を作るという考え方は、なるほど、これがユーティリティーファーストか、と思った。

第3章 Tailwind CSSを導入する

📝 この章に書いてあること
  • Tailwind CSS の導入方法について書かれてる
    • 初期セットアップ、ビルド
      • Tailwind CLI でセットアップしビルドする方法
      • PostCSS を使う方法
      • webpackを使う方法
      • Viteを使う方法
    • 設定ファイル
      • 設定ファイルのオプションの解説
  • Lightning CSS
    • Rust製のCSSツールチェイン
    • Tailwind CSS のバージョン 3.5以上で採用されてる
    • Oxide(オキサイド)と呼ばれるプロジェクト
    • 機能
      • minify
      • 古いブラウザの polifill 対応
      • 従来のものよりビルドが高速
        • これまではPostCSSのプラグインのサードパーティ製のものに頼ってたが、Tailwind CSS 自体の機能として使えるようになったので、高速になった

💁🏻‍♂️ 感想

環境構築はドキュメント通りに流したあとは、細かく深掘りしてなかったので勉強になった。バージョンアップだったり、何かしらのトラブル起きる時は、このあたりの設定値の漏れが原因になることが多そうなので、必要な時に見返したいと思った。Oxide の存在も初めて知って便利そうだなーと思った。

第4章 Tailwind CSSでマークアップする

📝 この章に書いてあること
  • Tailwind CSSが提供する基本的なユーティリティクラスの紹介
    • リファレンスとして使うと良さそう

💁🏻‍♂️ 感想

ざっと流し読みした感じ、普段使えてないユーティリティクラスを発見できたりしてよかった。どんなユーティリティクラスがあるのかざっと把握したかったり、素のCSSではこう書くけど、Tailwind CSS ではどう書くんだろうか、と思った時に読むと良さそうな章だと思う。本書でいちばん分量多い。

第5章 Tailwind CSSの背後にあるコンセプトを理解する

📝 この章に書いてあること
  • Tailwind CSS の背後にある設計思想が紹介された章
    • Tailwind CSS が提供してるクラス名以外の機能について解説されてる
  • Tailwind は未使用のクラスを消してるわけではない
    • 実際に利用されるクラスだけがビルドに含まれる
      • Just in Time(JITエンジン)
      • 考えられるクラス名をあらかじめビルドすることはない
      • Tailwind CSS のクラス名の法則をも満たす文字列を検出して、そのクラスに対応するスタイルを抽出する
        • つまり、最低限のクラスが含まれる css を出力するのは本番ビルドに限定される最適化のプロセスではなく、デフォルトの挙動
  • ディレクティブ
    • アットマークで始まり、CSSの動作を規定するもの
    • @apply ディレクティブ
      • コンポーネントレイヤー、セマンティックなクラスを定義できる
      • 一種の脱出ハッチ。あまり推奨されない。
      • Tailwind のメリットが消滅するので、あまり良い状況ではない
        • 命名を考える必要がある
        • バンドルサイズが膨らむ

💁🏻‍♂️ 感想

JIT エンジンで本番でも開発でも同じように最適化されたCSSを使ってるのは良さそうだと思った。ユーティリティクラスに目がいきがちだけど、Tailwind CSS のそれ以外の機能について把握できてよかった。

第6章 Tailwind CSSでコンポーネントを設計する

📝 この章に書いてあること
  • Tailwind CSS を使ったコンポーネント設計について書かれてる
    • ユーティリティファーストおいてどんな時にコンポーネントを作るのか?
      • 共通のレイアウトをラップするコンポーネントを作りたい時
        • 共通のレイアウト(スタイルを)を適用したい場合は、共通のクラスを変数に入れて使い回す方法もある
          • const wrapperClass = clasNames(”p-8”, “bg-gray-100”)
      • UIとして意味のある単位のコンポーネントを作るとき
        • <Button><Checkbox> など
        • 基底コンポーネントを作りたくなりがちだが基本的には必要ない
          • 基底コンポーネントとは <Box><Text> のようなコンポーネント
            • 必要ないのは、ユーティリティクラスがその役割を果たしてるから
    • 全ての UI がコンポーネントである必要はない
      • デザイナーが意思を持って命名してる箇所だけをコンポーネントと呼び、そうでない部分の抽象化はできるだけ後に回す
        • ページ全体をコンポーネントだけで構成するというより、コンポーネント部分とたとえば <div> の要素が混ざってても良いとする
          • ユーティリティファーストでセマンティックな意味づけをしなくて済むメリットに、デザイナーが名付けしてない要素に、エンジニア側が無理やり名付けする必要がなくなったということがある
        • コンポーネントという発想が薄く、ページ単位でしか考えないデザイナーに対しては、別のアプローチが必要そう
    • スタイルの上書きについて
      • 基本的には バリエーションを使う
        • cva(class variants authorities)
      • props で受け取るのは最終手段

💁🏻‍♂️ 感想

共通のレイアウトの構築する方法で、共通のクラスを変数に入れて使い回すというのが参考になった。デザイナーが意思を持って命名してる箇所だけコンポーネントにする話は、確かに、と思った。エンジニア側で何かしらの命名をしても、デザイナーとの共通認識にならないので、デザイナーと協力してやっていくのは大事だ、と改めて思った。

第7章 Tailwind CSSをカスタマイズする

📝 この章に書いてあること
  • 高度なカスタマイズ方法について書かれる
    • 設定ファイルの発展的な内容
      • クラスの抽出ルールの変更
      • クラスの命名規則をカスタマイズ
  • プリセット の作成方法
    • デザインシステムをライブラリにする
      • tailwind.config.js の形をしたオブジェクトをエクスポートするだけ
    • プリセットはどうやって設定ファイルをマージされるのか?
      • マージはデフォルト設定にたどり着くまで再帰的に行われる
  • JavaScript APIを利用する
    • コードから設定値を参照する
  • 独自のプラグインを作成する
    • いつ、なぜ、独自のプラグインを作りたくなるのか?

💁🏻‍♂️ 感想

共通したデザインシステムを使いたい場合、プリセットを配布するの便利そう。高度なカスタマイズが必要になった時にこの章をまた読み直したい。

第8章 Tailwind CSSを既存のプロジェクトに導入する

📝 この章に書いてあること

既存プロジェクトに Tailwind CSS を導入する方法について書かれてる

💁🏻‍♂️ 感想

既存プロジェクトに Tailwind CSS を導入することがあったら読み直そうと思った。

そもそも、スタイルの移行は、技術的な面だけだけで決めれることではなく、デザイナーが統一的なスタイルのルールを策定することに強いモチベーションがあり、密に協力する体制がなかったら時期尚早と書かれてあり、ほんとその通りだと思った。

第9章 ユーティリティファーストでデザインシステムを構築する

📝 この章に書いてあること
  • デザインシステムとは何か?
    • デザイナーと開発者がスタイリングにおいて同じ用語を用いいること、およびその状態を達成するための一連の仕組み
      • ドメイン駆動においてドメインエキスパートと同じ用語をソースコードで用いるべき話と似ていて、デザイナーはUIにおけるドメインエキスパートなので、デザイナーと同じ用語をコードで表現すべき
    • デザイナーとエンジニアの「契約」
  • 例外的なスタイルを表円する場合は、Arbitray Values を使う
    • py-[5px]
    • これを見るだけで、デザインシステムのルールにそってない例外的なデザインであると一目でわかる
  • デザイントークンとは何か?
    • デザインシステムという言語の最小の符号
      • カラー
      • フォントの種類
      • スペーシング
      • タイポグラフィ
        • フォントサイズと行送り(行間)を独立に設定すべきか?
          • 行送り(行間)は含めたほうが良い
            • 最終的なバウンディボックスを予測可能になるから
            • Tailwind CSS のデフォルトだと含まれてる
        • 行送り以外のプロパティはどうしたら良いか?
          • 例えば font weight
            • 含まないほうが無難
              • ユーティリティファースト発想に反するし、マークアップする側、コンポーネント側の設計に任せるべき
  • デザイントークンを管理するツール
    • Style Dictionary
      • Amazon が開発してる
    • 必要な要件
      • デザイナーと開発者が両方参照できる
      • デザインワークフローに組み込める
      • 開発エコシステムに連携しやすい
  • デザインシステムの作り始め方
    • トップダウンのアプローチ
      • 画面をUIコンポーネントに分解し、その中で共通の要素(<Button><Modal> など)を発見し体系化していくアプローチ
      • このアプローチをした場合、デザインシステムは、コンポーネント集として実装される
    • ボトムアップのアプローチ
      • 色やフォント、デザイントークンの下位のルールから実装していくアプローチ
      • このアプローチをした場合、最初から完璧を目指さなくてもルールを適用しやすい
        • トップダウンのアプローチだと、全てのコンポーネントが出揃わないと実装できないということになってしまう
          • 仕方ないので、デザインシステムを一旦無視して実装するという消極的なやり方になってしまう
💁🏻‍♂️ 感想

デザインシステムをはじめるにあたって、ボトムアップのアプローチとてもいいなと思った。Tailwind CSS の場合、まずシンプルに tailwind.config.js にデザイントークンの定義をしてあげるだけで、デザイナーと開発者が同じ用語を使える状態にできる。ボトムアップのアプローチをやりやすいフレームワークだと思う。

タイポグラフィの設定は、size と 行間以外にも 太さや letter spacing など、他にもいくつか要素があるので、これらをセットにしていい感じにまとめたほうがいいのでは?と思っていたけど、ユーティリティファーストの考え方としては、最低限 font size と行間だけはセットで定義しておいて、それ以外は使う側に任せたほうがいいという見解を学べてよかった。

何回も同じクラス名のセットを繰り返し使わないといけなくなるのめんどくさい気もするけど、そうするとユーティリティファーストの良さがなくなるので、素直にユーティリティクラスを書いていくアプローチが良いんだろうな。慣れもあるかもしれないと思った。

おわりに

全体を通してとてもいい本だった。Tailwind を学びながら、デザインシステムやデザイナーとの協力して仕事をしていくの大事だなと改めて思わされた一冊だった。