📚

Tailwind の命名を先送りできる嬉しさ

2022/10/01に公開

前提

Tailwind 好きとして、uhyo さんの「Tailwind 考」の記事を読ませていただき、とても共感だった。

Tailwind とデザインシステム

CSS フレークワークジェネレータな視点が欠けてたまま、Tailwind 語れれることも多い。デザインシステムをつくる(または、将来つくりやすくする)ためのフレームワークくらいの認識が広まって欲しい。

とてもよかったので、ぜひ元記事を読んでから進んでいただけると。

Tailwind は命名の苦しみからあなたを解放しないのか?

Tailwind は命名の苦しみからあなたを解放しない

一点だけ、ここについて基本同意の上で思うことがあったので、視点を補足的にネットに残しておく。

「命名の苦しみからあなたを解放しない」が、「命名の苦しみを減らすことができる」とおもっている。

命名を先送りができるから。

命名を先送りにする。とは

あるページをマークアップしていくとき、いきなり最初から理想のコンポーネントを作ることは難しいのではないだろうか。

多くの場合、まずはページ全体や、大きめのコンポーネントに HTML・CSS を書いていき、必要に応じてコンポーネントに分割していくことが多いのではないだろうか。

例えば、元記事にある、こちらのコンポーネントを例に使わせていただくと、

const UserProfile = ({ children }) => {
  return <div className="rounded-2xl p-8 bg-gray-50">{children}</div>;
};

const UserIcon = ({ src }) => {
  return <img className="w-24 h-24" src={src} />;
};

<UserProfile>
  <UserIcon src="cat.jpeg" />
</UserProfile>;

最初からこのように書くのではなく、はじめはこのようにコンポーネントを分割するのではないだろうか?

const UserProfile = ({ children }) => {
  return (
    <div className="rounded-2xl p-8 bg-gray-50">
      <img className="w-24 h-24" src="cat.jpeg" />
    </div>
  );
};

これを Tailwind を使わず、名付けずに style を書くならば、このようになるだろう。

.user-profile {
  border-radius: 1rem;
  padding: 2rem;
  background-color: rgb(249 250 251);
}

.user-profile img {
  width: 96px;
  height: 96px;
}

この時点で「.user-icon と名付けなくてよかった」ということが、 命名を先送りにした。 というということである。

Tailwind を使わないと、先送りにできないのか?

先程の例では、Tailwind をつかずとも、命名を先延ばしにできているようにも見えるが、img に style をあてることはあるのだろうか。

.user-profile img {
  width: 96px;
  height: 96px;
}

scoled style になっている小さいコンポーネントなど、影響範囲が見渡せる状態であれば、HTML タグ に style 当てるパターンは個人的にはありだと思っている。

でも、影響範囲を把握できない箇所に HTML タグに直接スタイルをあてることはしないだろう。
例えば img が2つ使う必要があった時に、クラスを使わずこのようにはあまり書かない。(書く人もいる。このパターンは後述)

.user-profile > div:first-child > img {
  width: 96px;
  height: 96px;
}

つまり、コンポーネント分割していない状態で、クラス名を命名することになる。

一方 Tailwind は 直接 html に <img className="w-24 h-24" src="cat.jpeg" /> と書いているので、命名しなくても style を安全にあてることができる。

今回補足したい視点のポイントを整理すると、命名コンポーネント分割のタイミングは違うという点。

そして、Tailwind は分割のタイミングで初めて命名すればよいというのが、嬉しいと思っている。

なぜ、先送りにできると嬉しいのか?

意見が分かれるかもだが、私は YAGNI 的にコンポーネント分割は必要になったタイミングでしたほうが良いと考えている。

私の考える必要になったタイミングは、

  1. ループ処理含む、2箇所以上で同じレイアウトが必要なとき
  2. style 影響範囲が把握が難しくなり、スコープを区切りたいとき

が、style に関するもの[1]としては主な理由ではないだろうか。

嬉しいポイント1:構造化とレイアウトに集中できる

イメージがつくように具体例として、zenn のこの部分をマークアップをするとする。

私ならば、最初のマークアップ時は ArticleListItem しかコンポーネント分割しないと思う。

この時点で Tailwind を使わない場合、 ArticleListItem のコンポーネント内では、.article-title .article-thumbnail .user-name .user-thumbnail .date など名付けないといけない。 Tailwind ならばこの時点ではしなくて良い。[2]

最初の一番 style をたくさん当てるタイミングで 命名への思考を最小限に抑え、レイアウトを組むことだけに集中できる のが、嬉しいポイントその1である。

もしコンポーネント分割しなければ、そもそも命名していないということでもある。

嬉しいポイント2:命名の無駄を減らせる

また、このあとコンポーネント分割する時も考える。
例として、他の場所でも使っているので、ユーザーアイコンとしてコンポーネント作ろうとしたとする。[3]

このとき、.user-thumbnail よりも .user-icon のが命名が適していると思うかもしれない。
多くの場合、たくさんのレイアウトが出揃ってからのほうが、正しい命名をつけることができる。

ここで .user-icon とつける命名コストは Tailwind にもかかるので先延ばしと表現したが、クラスとして命名した .user-thumbnail は無駄になっていたと捉えることもできる。

先延ばししたことで、命名コストを減らせたのが嬉しいポイント2である。

嬉しいポイント3:コンポーネント化しやすい

クラス名が適切に命名されていた場合は、そこまで違いがない部分だが、前述したように HTML タグにスタイルを当てる人もいる。
例えば、.user-thumbnail がこのように書かれていたとする。

img {
  border: 1px solid #eee;
}

.article-list-item > div:last-child > img {
  width: 96px;
  height: 96px;
}

コンポーネント分割にすべき HTML と CSS それぞれ特定する必要があるのだが、適切な命名がされていないと、CSS の影響範囲の特定がとても難しい。

その点、Tailwind さえ使ってくれていれば、「HTML タグにスタイルを当てる」問題発生しないし、HTML の場所さえ特定してしまえば、そこだけコンポーネントに移動すれば完了である。

別視点で、tailwind class 多すぎて、HTML の特定をするのが難しいのでは?と考える人もいるかも知れないが、Developer Tools から class コピーし、まるごとファイル内検索すれば意外と簡単に特定できる。これで探せない場合は、さすがに分割しなさすぎではある。

想定質問

styled-components や、インラインスタイルできるよね?

そのとおり。ので、tailwind の次に好き。

しかし、一度変数にいれて HTML に加える書き方も一般的であり、その場合はこの記事における命名の先送りの嬉しさはなくなる。
この選択が存在する(制限できない)ことと react 以外の相性の問題として、私個人は Tailwind が良いと感じている。

インラインスタイルは...、結構いいかもね。

最初からコンポーネント分割はしっかり行えばよいのでは?

そのとおり。実はここまでの嬉しさは「私は YAGNI 的にコンポーネント分割は必要になったタイミングでしたほうが良いと考えている。」という私の前提の上、成り立っている。

元の記事にも、こう書かれている。

本当に、Tailwind を使っていたとしてもコンポーネント分割はしっかり行なったほうがよいと筆者は考えています。1 つのコンポーネントに属するマークアップの塊がでかいというのは 1 つの関数がでかいのと同じ状態であり、通常それは望ましくありません。また、より即物的な問題として、マークアップは普通のプログラムに比べてインデントが変動しやすい傾向にあり、スタイルが変更される際には大胆に修正されやすいため、破滅的なコンフリクトを生み出しやすいです。あらかじめコンポーネントに分割しておくことで破滅フラグを回避してください。

こちらも「Tailwind を使っていたとしてもコンポーネント分割はしっかり行なったほうがよい」は同意であるのだが、「コンポーネント分割を"最初から"しっかり行うことが難しい」と思っているので、このように思っている。

最後に

もうひとつ問だけ。「デザインにこだわりがなく、最低限整っていればいい場合」と「逆に、デザインシステムをしっかりと整備しそれからの逸脱を防ぎたい場合」ではない場合、どの場合で存在してよいのか?と考えた時、
ウェブ制作時くらいしか思いつかないので、ウェブアプリケーションを作る場合にいつ存在するのかを考えているところではある。

そういった意味で、Tailwind クラス名なんて絶対覚えたくない!など Tailwind ではだめな理由がなければ「気軽に採用しててほしい」と考えているので、その点は元記事と私の考えは違うのかもしれない。

脚注
  1. ロジックとして分割したいとき。など、他にもタイミングは存在すると思うが、ここでは style に関する動機のみについて考える。もし、style に関する動機があれば、教えてもらえると嬉しい。 ↩︎

  2. 実際の zenn とは異なり、あくまで例として、使わせていただいております ↩︎

  3. 実際の zenn は共通コンポーネントとして管理されないと思いますので、あくまで例です。 ↩︎

GitHubで編集を提案

Discussion