なぜ Tailwind が人気になったのか?
自分なりに納得するために悶々と考えてみました、という日記です。
具体的なコードについては触れません。
抵抗感を感じているコーダーの人の一助になれば嬉しいです。(ポエムご容赦を)
css の パラダイム・シフト?
Cssを書き始めて十余年、いくつかの大転換点を目の当たりにしてきました。
(脱Table、css3、cssメタ言語、css framework、 oocss/BEM、 scoped css …等)
Tailwind の掲げる Utility-First
も、これらと同程度のインパクトがあると感じます。
古参コーダー程 強い抵抗感を感じる?
「cssの命名はセマンティックでなければならない」
これは、いつ刷り込まれたアイデアだったのか。
Tailwind世界線から観察すると、これは完全に天動説。
# 公式より
Rapidly build modern websites without ever leaving your HTML.
“Best practices” don’t actually work.
潔さ。 地動説の匂い。
Utilitiyの組み合わせて素早く組む、という事は当然、黎明期から何度も試されて失敗してきて、 「バッドプラクティスである」 という事をみんな知っている。
故に、否定論者の気持ちを痛い程わかるし、自分自身も正直半信半疑な部分もある。
しかし、これはパラダイムの転換点として、多くの賛同を経て流行に至った。
このUtilitiy思想がどうして今、改めて受け入れられているのだろうか?
何故セマンティックな名前をつけるようになったのか?
「その命名で正しい?」
cssコーディング中、何百回も自問自答することになる。
必死に文章構造を読み取り、その見た目が持つ意味合いを推測することに時間を使うことは当たり前だった。 超乱暴な言い方だが、「命名こそがcssコーディング」だ。
でも最初期の css は必ずしもセマンティックな名前を持っていなければならない、というものではなかった。
では、なぜそのような文脈に沿った名前を都度考えるようになってしまったのか?
以下の3つ理由が当てはまるような気がする。
- 見た目情報に一意のアイデンティティを与えるには、抽象的すぎる事。
- HTMLという文章構造に寄り添っているcssの特定に、HTMLの文脈をそのまま利用するのが便利だった事。
- 簡単に汚染されるが故、命名が名前以上の構造的重要性を担ってしまった事。
なぜ名前空間が必要だったのか?
cssが潜在的に抱えている「すべてがグローバル」という問題点。
これを補う苦肉の策として生まれたのが、「命名を工夫する」というアイデアだ。
亜種はあるが、最終的に BEM
がデファクト化した。
.block__element--modifier
非常に冗長なclass名が特徴的だ。
この「奇っ怪さ」は、「誰が見ても一目瞭然」という事もあり、オンボーディングが楽になるというおまけ付き。
現状今日でも、cssがcssである以上、これはひとつの最適解であるように思える。
scoped時代?
一方 React / Vue
などの潮流から来ている scoped css
が隆盛している。
好きな単位で 「閉じた系」を作り、汚染の心配を無くす事ができる。
しかし、長らく奇っ怪な名前を使ってきたが故に、この 「閉じた系」 でどんな名前をつけてよいのかわからず、 Scoped なのにも関わらず BEMで書いたり、「本末転倒」な事をしがちな気がする。 (笑えない)
要するに、プロジェクト毎に、誰かがルールを決めて、皆がそれを守れば良い。
ただそれだけの事なのだが、それこそが最も面倒であり、とても難しい。
果たして、どんなルールが正解なのか?
名前空間は不要になった?
React
なんかでは特に難しいように感じる。
jsx
の世界では、css は js で書かれるし、作法も色々。 正直、無茶苦茶な話だなと思う。
(styled-jsx
, css modules
, styled components
, emotion
… )
魔改造されたcssもどきは、それぞれ微妙に作法が異なるため、命名も微妙に最適解が変わってくるはずで、それがさらに、プロジェクト単位で微妙に違う。書く場所も。
ルールを決めるのも、決まっているルールを紐解くのも、どちらも非常に大変な作業になる。
css1行のためにどれだけの事に注意を払う必要があるのか。
ここで気がつく。そもそも ルールいるの? 名前いるの?
頭でっかちで厳密に考える程、超重要で非常に面倒なことだが、実はどうでもよい。大したことない問題なのだ。
cssへの興味に割く時間を無くし、本質に時間を使いたいというニーズに、Tailwind は非常にマッチしているように感じる。
見えない設計ルールを意識する必要がない
注目すべきは名前だけではない。
Tailwindは、すべてのプロパティの単位を統一して、その事を一切気にしなくてよくしてくれているのがすごい。
オンボーディングに時間がかかる最大の理由は、プロジェクトルールの把握だ。
「マージンはどんな単位なの? 」
「フォントサイズはどんなルールなの?」
「色はどう管理されているの?」
「レスポンシブはどう指定すべき?」
全てのフレームワークは微妙にルールが違い、それがひと目ではわからないように隠匿されていて、記述箇所を探すのにも一苦労だ。
生cssで設計されている場合にはもっと大変。自由度が高すぎる故に可能性がありすぎる。ドキュメントがなければ設計者に口頭で聞くか、漠然と適当な10pxくらいの隙間
が随所に生まれる。
Tailwindはその場で、.my-4
.text-2xl
.bg-green-500
.md:flex
のようなクラスを見ただけで、成り立ちから、何をすべきかが完全にわかるというのは尋常ならざる見事な設計だ。
Atomic Design の粒度変更が容易?
コンポーネント開発で遭遇する頻出パターンからも考えてみる。コンポーネント思考で設計する補助線として、Atomic Design
のような考え方が生まれた。
でも、その実態は 「デザイナー と コーダー の協業を助ける共通言語」でしかない。潜在的な問題は当然いくつも持っている。
理にはかなっているものの、あくまで 「フロントエンド目線でデザインを見ている」 事が原因かもしれない。
「デザイナーが見ているデザイン」 との「思惑のズレ」がどうしても生まれる。
そしてこれは、開発途中、もしくは改修改善プロセスで何度も噴出する。
デザイナーの思考 : 全体から作る。 細部は最後に詰める。
コーダーの思考 : 細部から作る。 積み上げながら全体ロジックを構築。
強引に要約すると以下のように設計してく事が多い想定。
デザイナー : ... Organisms → Molecules → Atoms
コーダー : Atoms → Molecules → Organisms ...
このプロセスの違いによって、どうしても 「粒度の変更」 が頻繁に発生する。
「この部品」が Molecules
なのか Organisms
なのかは、実はデザインした時点で、誰にもわからない。
「正解」は、その後の 改修・拡張 によって簡単に変わってしまう。
理想的には Atoms
から実直に積み上げていくべきだが、事前の設計のコストも高く、冗長・無駄になりすぎる事が多い。
故に Organisms
から切り出していくようなアプローチを取りたくなるが、cssの存在が大きなストレスになる。
Organisms
から Molecules
を切り出すには、密結合したCSSを慎重に引き剥がす作業が発生する。
ロジックにもべっとり癒着しているだけではなく、セマンティックに名前にも結合している場合にとてもつらい作業だ。
大げさでなく、物によってはこれだけで一日がかりになることも。
これが Tailwind で書かれていると、ほぼコピペだけで切り出しが可能になるケースが増えてくるように感じる。
さらに、Tailwindで書かれている場合、別のプロジェクトですら再利用可能なコンポーネントとして組むことができるため、長く使うほど利便性が向上していく。
framework に閉じ込められる心配が少ない?
数多くの css Framework が誕生し、使われてきた。
導入が楽で、非常に強力。
しかし数年後、リニューアルなどの折に、取り外しのコストに愕然とすることになる。
簡単に始められ、最高にハイになるが、簡単にはやめられない。麻薬だ。
一方、Tailwindはあくまでただの Utilitiy集でしか無い。
コンポーネント集のようなフレームワークに比べ、ずっとローレベルなので、 併用している React / Vue のようなフレームワークの壁を簡単に乗り越えられる。 微細な差はconfigにまとまっているので、ソースコード上で考えることはほとんどない。
長期的に 脱Tailwind の流れで、別のフレームワークに移行する必要が出たとしても、
原理上そこまで取り外す必要性はないように感じられる。ゆるく相乗りできるように見える。
(この麻薬は、いつだって自分の意思で簡単にやめられそうだ...今の所)
HTMLが酷くなる問題 ?
某所で話題になっていた、異常に長いし何がなんだかわからないソースコード
という指摘。
これに関しては 「BEMの奇っ怪さ」と大差ないし、そもそも、コンポーネント化し、入れ子状に隠匿する前提なので、無視して問題ないと個人的には思います。
わざわざ @apply
で圧縮する必要すらもなさそうです。
逆に言うと、カプセル化できないプロジェクトなのであれば、Tailwindは向いてないのかもしれません。
強引にまとめ
Tailwindを使うと良さそうな場面。
- CSSは十分に理解できている
- コンポーネント思考で開発したい
- コンポーネント集にロックインされたくない
- 名前考えるのだるい。
- 素早くたくさん作りたい
- すでにTailwindで作ったものを他所でも流用したい
他にもまだまだメリットはありそうだが、一旦の結論。
Tailwind はもちろん「銀の弾丸」ではなく、従来の設計のほうが優れている場面も当然あると思います。
そして、cssを踏襲しているようで、生cssとは微妙に違っているという点は留意する必要があって、理解が十分でないうちに手を出してしまったり、あまりに信奉しすぎると、後々苦労しそうだという事は想像に難くないです。
技術にこき使われないように、注意して付き合っていきたいです。