tailwindcss のコンセプトとメリットについての考察

目次

こんにちは、CADDi でフロントエンド エンジニアをやっている桐生です。この記事は CADDi Advent Calendar 2020 の7日目の記事になります。

昨日の記事はモリさんの あえてケイスケ・ホンダのようなデザイナーになるには でした!まだご覧になっていない方はぜひ目を通してみてください!

本日は、最近触っている tailwindcss についてお話できればと思います。

[toc]

tailwindcss とは

tailwindcss は数あるCSSフレームワークの1つですが、Utility first というアプローチでスタイルを組み上げていく点がユニークで、OOCSS, BEM, SMACSS など、これまでのCSS設計アプローチとは考え方が大きく異なります。

tailwindcss では p-6, max-w-sm などの CSS class を utility class と呼んでおり、これらの utility class は1つ1つのCSSプロパティに対応するほど細かく primitive なものとしてあらかじめ用意されています。padding のサイズ違いなどにもそれ専用の class が提供されているので、CSSそのものを書く代わりに、用意されている utility class をHTMLのclass属性に追加してスタイリングしていく、という開発スタイルになります。tailwindcss が提供しているものはこの utility class のみで、他CSSフレームワークがよく提供しているようなコンポーネントという大きさのレベルのスタイルは存在しません。これが tailwindcss の Utility-First というアプローチです。以下は tailwindcss の公式ドキュメントからの引用になります。

<!-- 公式ドキュメントから引用 -->
<!-- class 属性に付与さているのは全て utility class -->
<div class="p-6 max-w-sm mx-auto bg-white rounded-xl shadow-md flex items-center space-x-4">
  <div class="flex-shrink-0">
    <img class="h-12 w-12" src="/img/logo.svg" alt="ChitChat Logo">
  </div>
  <div>
    <div class="text-xl font-medium text-black">ChitChat</div>
    <p class="text-gray-500">You have a new message!</p>
  </div>
</div>

tailwindcss のメリットは?

tailwindcss の公式ドキュメントでは、Utility-First アプローチをとることで、3つのメリットがあると言っています。

1. CSS設計・運用コストの低減

You aren't wasting energy inventing class names. No more adding silly class names like sidebar-inner-wrapper just to be able to style something, and no more agonizing over the perfect abstract name for something that's really just a flex container. class 名の発明に無駄なエネルギーを使わなくて済む。何かをスタイリングするためだけに sidebar-inner-wrapper のようなばかげたクラス名を追加したり、単なるフレックスコンテナに対して抽象化した名前を悩んだりすることがなくなる。

CSS設計の経験のある人は誰しも悩んだことがあると思います。CSS class のネーミングは本当に難しい作業です。UIコンポーネント構造を抽象化して class 名として表現しなくてはなりません。それに加え、ネーミングルールの設計、ネーミングルールの遵守徹底など、非常にコストのかかる作業でもあります。

Utility-First アプローチをとることによって、そもそも class 名のネーミングという作業自体がなくなるので、ネーミングにかけていた時間をゼロにすることができるということですね。ネーミングという行為自体が不要となるので、それに関わる設計・運用コストもなくなり、一石三鳥というわけです。

2. CSS100%再利用によるCSSサイズ肥大化抑止

Your CSS stops growing. Using a traditional approach, your CSS files get bigger every time you add a new feature. With utilities, everything is reusable so you rarely need to write new CSS. CSS の肥大化を止めることができる。従来のアプローチを使用すると、新しい機能を追加するたびにCSSファイルが大きくなる。utility を使用すると、すべてが再利用可能になるため、新しいCSSを作成する必要はほとんどない。

tailwindcss が提供する utility class は、CSSプロパティ1つ1つに対して用意されるほど細かいので(primitive utilities という呼ばれ方もしています)、100%再利用可能です。ほとんどの場面においては用意されている utility だけで十分で、開発者が独自にCSSを実装する必要がないということですね。

3. スタイルの変更をHTMLローカルで安全に行える

Making changes feels safer. CSS is global and you never know what you're breaking when you make a change. Classes in your HTML are local, so you can change them without worrying about something else breaking. 変更が安全になる。 CSSはグローバルであり、変更を加えたときに何を壊しているのかが分からない。 HTMLの class はローカルであるため、他の何かが壊れることを心配せずに class を変更できる。

utility class は primitive なので、class 内のCSSを変更するということはありません(もちろん変更することは可能で、その場合は config ファイルを介して変更することができます)。もしスタイルを変えたくなった場合は、CSSを変えるのではなく、HTMLのclass属性に付与しているCSS class自体を変えることになり、

<div class="p6"></div>
<div class="p6"></div>
    ↓ 1つだけ太字にしたい
<div class="p6"></div>
<div class="p6 font-bold"></div> <- 影響範囲はここだけ

HTMLの変更は影響範囲がそこのみに限定されるため、非常に安心して変更することができるというわけです。よくCSSグローバル変数だと揶揄されますが、それとの対比で「HTMLの class はローカル」とはうまい例えだと思います。

tailwindcss のデメリットは?

良いことづくめのような話に聞こえますが、果たしてデメリットはないのでしょうか?

インラインスタイルじゃダメなの??

HTML の class 属性に utility class を付与していく様はまるでインラインスタイルを書いていくかのようです。

Why not just use inline styles?

ところが、

  • インラインスタイルで埋め込まれた値は magic number となってしまう
  • インラインスタイルは media query が使えない
  • インラインスタイルは擬似クラスが使えない

との理由から、インラインスタイルはむしろ悪手となり、utility class を差し置いて採用する意味がありません。

メンテナンス性は大丈夫??

Maintainability concerns

例えばボタンのような非常に基本的なコンポーネントであっても utiliy first で実装すると相当数の CSS class が class 属性内に展開されます。

<!-- 公式ドキュメントから引用 -->
<button class="py-2 px-4 font-semibold rounded-lg shadow-md text-white bg-green-500 hover:bg-green-700">
  Click me
</button>

このボタンスタイル一式を様々なところで使いまわしたい時、毎回コピーしなくてはいけないのだとすると、メンテナンス性を著しく損なうことになりますが、これについてはどう対処すればよいのでしょうか?

tailwindcss としての回答は「カスタムCSS class を作らずに template や JavaScript Component を作れ」です。 Extracting template components 一旦カスタムCSS class を作ってしまうと、そこからネーミングコスト、CSS肥大化につながってしまうので、template や JS Framework にコンポーズする責務を任せ、CSS側はあくまで Utility-First に徹することを推奨しています。

こうすることで、Utility-First のメリットを損なうことなく、メンテナンス性を担保することができるというわけです。

CSSプロパティ <-> utility class の翻訳大変じゃない??

CSSプロパティ1つ1つにあたる utility class が提供されているとなると、その数は膨大で、覚え切ることは難しいです。普段CSSを書き慣れた開発者にとっては、CSS プロパティ -> utility class の翻訳がもどかしく感じるかもしれません。

そこで tailwindcss では、DXを向上させるための VS Code extension を提供しています。

Tailwind CSS IntelliSense

これにより IntelliSense が効くようになって、効率的にスタイリング作業を進めることができます。実際、私も tailwindcss を触り始めた時にもどかしさを感じていたのですが、この extension を入れてからストレスが減ったと思います。

(閑話)いかにして tailwindcss は生まれたのだろう?

tailwindcss のドキュメントの一節にこうあります。

Extracting template components

It's very rare that all of the information needed to define a UI component can live entirely in CSS — there's almost always some important corresponding HTML structure you need to use as well. UIコンポーネントを定義するために必要なすべての情報が完全にCSSに存在することは非常にまれ。ほとんどの場合、CSSと対応するHTML構造が必要になる。

昔から、見た目と構造は分離すべしと言われてきましたが、昨今のCSS設計手法では、むしろコンポーネント構造をいかに抽象化し、適したネーミングを CSS class として表現するか、ということに重きが置かれてきたように思います。よくよく考えるとこれは、見た目と構造が分離されるどころか、むしろ結びつきを強める方向に進んでしまっていたのではないかと思うようになりました。

作者は、これこそが根本的な原因であり、その因果として

  • 構造を抽象化したCSS class名 -> CSS設計コストの増大
  • 構造に依存したCSS -> CSS再利用性の低下

という問題が生じているのでは、と考えたのではないでしょうか。そして、その解決策を考え突き詰めた結果として Utility-First というアイディアに至ったのではないか、と推察します。tailwindcss が生まれた背景には 見た目と構造の完全分離 という設計思想があるような気がしました。

そう考えると、tailwindcss の Utility-First アプローチは、単なる奇抜な手法ではなく、現状の問題点への深い洞察から導きだされた論理的な解決方法であり、画期的な手法だ!と感心せずにはいられません。

これはあくまで私の解釈ですが、皆さんはどう思われますか??

まとめ

tailwindcss は primitive な utility class を提供することで、

  • CSSの設計コスト、運用コストを下げる。
  • CSSの再利用性を高める。
  • CSS肥大化を防ぐ。
  • スタイルの変更容易性を上げる。

をもたらしてくれるものである、と言えるのではないでしょうか。

現在 CADDi では、styled-components を使用したスタイリングを行っているのですが、特にCSSの再利用性に課題ありと個人的に感じています。今回 tailwindcss についてのコンセプトとメリットについて理解を深めたことで、課題解決に期待できそうなので、今後試験的に導入することも考えていきたいなと思っています。

ただ、私自身、tailwindcss を触り始めてからまだ日が浅いこともあり、デメリットらしいデメリットに当たっていないだけの場合もありますので、今後、いろいろと知見を溜めて行ければと思います。

付録

この記事を読んで「tailwindcssなんか良さそうだな、今すぐ試してみたい」と思って下さった方もいるのではないかと思います。いたら嬉しいです。そんな方にぜひ。

tailwindcss をとりあえず触ってみたい人向け

公式の playground があるので遊んでみてください。 https://play.tailwindcss.com/

project に組み込んで使ってみたい人向け

tailwind をセットアップしたプロジェクトを作ってみたので、お好きに使ってください。README.md にはセットアップ方法をまとめてありますのでご参考ください。

おわりに

CADDi では先日採用サイトをリニューアルしたばかりです!非常にカッコよく仕上がっているので、興味ある方はぜひご覧いただければと思います!

https://corp.caddi.jp/recruit/