情報が錯綜しているのでちょっと躊躇しているTailwind
私が「錯綜している」と感じるのは、Tailwindおすすめ記事において比較されてる対象がよくわからないからだと思う。
例えばよく挙げられる「クラス名を考えなくてよい」というメリットは、すでに「React等のJSのフレームワーク+CSS in JSやCSS Modules等のスタイル用ツール」によってほとんど解決されている問題なので、最初は「BEMを使って素のHTML+CSS書いてる人向けなのかな?」と思った。でも多くの記事は最終的にReactとかVueとか前提の話をしているので……論点がよくわからない……。
(それとも、React+スタイル用ツールの組み合わせでも解決されてないのかな……?)
本家を読んで、 「素のCSSを書く機会を減らすことで、デザイントークンを使い忘れることを防げる」「デザイントークンの使用をほぼ強制できる」 というメリットは理解した。(けどここを推してる人は少ない気がする……?)
「BEMのようなクラス名を考えなくてよい」という点は、React等のフレームワーク+スタイル用ライブラリの環境下では、すでにほぼ解決されている問題だ。React等を使っている案件ではここは別に大したメリットではない。(※例外は後述)
かといって、BEMと素のHTML+CSSを使っている案件にTailwindを入れて「クラス名を考えなくてよい」メリットがありがたいかといえば、全くそんなことはない。むしろそんなことをしたら地獄だ。classに大量のユーティリティクラス名を記入するというスタイルは、HTMLがコンポーネント化されている前提でなければ、到底メンテナンスコストを許容できない。
このメリットを語っている人は、どういう状況を前提にしているのか、謎……。
先ほど「例外は後述する」とした、React+αで解決されていない問題として残っているのは:
- コンポーネントスコープのごく短いクラス名すら考えなくてよくなるというメリット
- そんなに大きなメリットとは思えないが、あるにはある
- CSS読み込み順や詳細度との闘い
- CSS in JSでもCSS Modulesでも、エッジケースではこの闘いが残る
- Tailwindだとここから解放されるのかな……?
Tailwind vs CSS ModulesとかTailwind vs CSS in JSとかいった文脈で語られているものもあるけど、そこってそもそも比較対象なのかな……?共存するものなんじゃないのかな?
私はまだ本番案件でTailwindを使ったことがないんだけど、仮にTailwindを採用しても完全にCSSを排除できるわけではないと感じている。
デザインのすべてを自分たちの裁量で判断できる案件ならいけるかもしれない。ただ、マイクロインタラクションのCSSアニメーションや外部サービスのウィジェットや広告等のために発生する特例対応など、CSSを書かなきゃいけない場面はいずれ出てくるよな~と思っている……。
「共存することを前提として、なるべくCSS ModulesやCSS in JSで書くのを避けてTailwind側の機能を使うべき理由」って文脈での比較……なのかな?
あるいは本当にTailwindだけでなんとかすることが可能という主張だったり……?
私はCSS Modulesが好きなのでこの記事のここにはツッコミを入れておかねばならない:
なんか最初はCSS標準技術に近いやつだなって思ってたんですけど、結局の所これ、webpackをゴニョゴニョして無理矢理スコープっぽくしてるだけなんですよね。GatsbyだのNext.jsは、webpackに乗っかっているReactのその上に存在するレイヤーなので、なんかこのwebpackの機能に依存しているCSS Modulesという存在が、フレームワークとうまいこと噛み合ってねーなと感じました。この後書くCSS in JSもほぼほぼ同じことをやっているんですが、JSファイルの中でチョロっと書けてしまって。それに対してCSS Modulesはお行儀よくCSSファイルにしないといけないんですよ。そしてwebpack依存技術だぞっと。
https://qiita.com/Takazudo/items/78ee15564bfefdea844c#webpack依存技術である
CSS Modules自体はコンセプトのようなもので、別にWebpack依存技術ではないです。ただし、Webpackのcss-loaderが最もよく使われているCSS Modules実装であり、ほとんどの場合はこれを使うことになるというのはまぁ間違いではない……。
他の実装がないわけではなく、Next.jsではすでにWebpackのcss-loaderを使わず自前実装しているらしいし、より汎用的な実装としてPostCSSプラグインのpostcss-modulesもParcelとかで実際に使われている様子。
(というかそもそも、TailwindやCSS in JSライブラリに依存するのはよくて、それよりユーザーベースが大きく歴史も長いWebpackに依存するのはダメという感覚がよくわからないけど……)
(文章の流れ的に、一番重要な理由は「CSSファイルを分けるのがめんどくさい」で、依存云々はおまけなのかな?)
(追記:Next.js等のスタックを使っていない前提で、自分でwebpackを導入して設定するコストがかかるという話かも?)
私はReact再入門者で、 Next.js上でReact+TypeScript+CSS Modules+SCSSで構築しているんだけど、正直「TailwindのユーティリティがSCSSのmixinだったらよかったのになぁ」と思っている……。
Tailwindの@apply
とか、configに書く諸々とか、それSCSSじゃダメだったのかなぁと思うことが多い。既存のCSS/SCSS資産が使えるし、仮にTailwindが死んでも取り出しやすいし……。
逆にSCSSを使わない人からしたら、JSベースの方がいいと感じるのかもしれない?
(私はJSや型定義のないjsonは一行も書きたくないTS派なので相容れないのですが……)
調査課題:
TailwindはZero-runtimeだという情報とそうじゃないという情報が両方見つかったんだけどどっちが正しいんだろう?
メモ:
公式にzero-runtimeって書いてあった。
Tailwind CSS works by scanning all of your HTML files, JavaScript components, and any other templates for class names, generating the corresponding styles and then writing them to a static CSS file.
It's fast, flexible, and reliable — with zero-runtime.
https://tailwindcss.com/docs/installation
私が懸念している点は主に3点:
- 独自記法であることのデメリット
- 学習コスト(これはまぁ大したことなさそう?)
- Tailwindへのロックイン(フレームワークだから当然ではある)
- classに無意味な値が残っていても問題はないという意味では「外しやすい」フレームワークではある(外せるだけだが……)
-
An API for your design system.
を謳ってるけど、別に「インターフェース」として設計されてるわけじゃないよな~?ユーティリティとAPIって違わない? - カスタムユーティリティクラスを作る機能は間違いなくAPIだけど、ここのこと言ってるのかな?
- メンテナンスコスト
- JSX(TSX)がむちゃくちゃ汚くなる点、各所で「問題ではない」って言われてるけど、コード例はどれもシンプルに読みにくい
- 汚くならない方法ないのかな……
- TypeScriptとの相性
- そもそもがclass名だけで解決しろというコンセプトだからあまり関係なさそう?
ちょっと触って調べているうちに、Tailwindの本質は「ユーティリティクラスを生成するデザインシステム用API」で、汎用的に使うユーティリティクラスはすでにビルトインされている、というものなのかなと感じたのだけれど……
それは……SCSSでやりたかったな…………
私はJSでCSS(になるもの)を記述するのは基本的に避けたい派です。
SCSSはCSSのスーパーセットなので、CSSでやっていたことを移植するときにはそのまま使えるし、何かの事情で部分的にCSSを切り出さなきゃいけない(例えば、部分的なスタイル記述機能のあるブログサービスにコピペして使い回すとか)場合もそこまで手間ではない。
また、文法や記法がCSSから離れれば離れるほど、CSS自体のアップデートに追従するためのライブラリ側のメンテナンスコストも上がり、プロジェクトの存続に直接響くと考えています。リメンバーCoffeeScript。(Tailwindくらい大きいプロジェクトなら問題なさそうだけど、有象無象の無名CSS in JSに賭けるのは危うい。)
今のところ、SCSSの変数やmixinを使ったオレオレデザインシステムで困ったことがないんだけど、大規模になると話は変わってきそう。また開発速度は間違いなくTailwindの方が早い。
メモ:比較対象がはっきりしてるわかりやすい記事があった
使ってみて問題になったところに関する情報
挙げられている問題点
- きちんとルールを設けずTailwindと自前のCSSが混在する状態になってカオスになった
- デザイン変更時に変更箇所が多くなった(コンポーネント化してなかったのかな……?)
ただ、この記事で提案されている解決法「各コンポーネントにクラス名をつけておいて@apply
でまとめる」は、また「クラス名を考える」ところに逆戻りなのでは……。
Tailwind思想的には、コンポーネントという単位のクラスではなく、デザインシステム上の「ユーティリティ」単位のクラスを作るために@apply
を使うべきなのかな~と思ってたけど、公式ドキュメントの@apply
のページは普通に.btn
とかのクラス作ってますね……
根底にあるのは"An API for your design system."だけど、そこまで考えず「便利なユーティリティ集」として使っても便利だよ、というくらいの温度感?
検索すると「クラスを作って@apply
で書いた方がいい」派はけっこう多いみたい……その場合、クラス名の問題はどうしているんだろう……?やはりCSS ModulesかCSS in JSを使ってるのかな?
「コンポーネントにクラス名をつけておいて@applyでまとめる」方式、公式に否定されてない……?!
If you’re going to use
@apply
, use it for very small, highly reusable things like buttons and form controls — and even then only if you’re not using a framework like React where a component would be a better choice.
https://tailwindcss.com/docs/reusing-styles#avoiding-premature-abstraction
公式の考えは「React等でコンポーネント化されているなら、HTMLテンプレート(JSX)上のclass属性が汚いのはメンテナンスコスト的に許容できる範囲であり、クラス名を考えなくてよい/1ファイルで完結する/影響範囲が閉じられている/CSSバンドルが小さくなる、というTailwindのメリットの方が大きい」といった感じで、それを覆す@apply
は限定的な状況での使用を推奨しているように見える。
Tailwind、わかんね~!