Tailwind CSSと和解した話

Created: 4/19/2022Updated: 5/22/2022Tags:CSSTailwindWeb


既に白熱した議論が交わされたTailwindCSSですが、実際に使ってみて「巷に上がるデメリットを読んで敬遠するぐらいなら、一度使ってみてほしい」 と感じたので、今更ながら、肯定側として語らせていただくことになります。

※TailwindCSSが何であるかの説明は他に譲ります。

はじめに

みなさんはTailwindCSS、好きですか?私は好きです。今は。

タイトルの通り、私のTailwindCSSの第一印象もあまり好意的ではなかったので、一見して様々な抵抗があることも理解出来ます。例えば、

  • 実質的にインラインでアンチパターンなのでは
  • クラスが多く見た目がごつい
  • CSSのプロパティ名との対応を覚える必要がある
  • 移植性が無い
  • プリプロセッサが必要になる

という意見が考えられます。

しかし、素のCSSやSass、CSS ModulesやStyled Componentなどを試してみた上で、現在はTailwindCSSに落ち着いています。それは、「カスタマイズが必要」なWeb開発におけるスタイリングの最適解だと考えているからです。

前提

もし、デザイン的に例えばMUIを組み合わせで事足りるのであればそれがベストだと思います。

ただし、CSS Modules、Styled Componentなどと比べるならば、 「見た目をカスタマイズしたい」という要件を前提にするべきです。

この記事は、React、Vueなどのフレームワークでフロントエンドを開発している方々を想定しています。

Tailwindはアンチパターンを推奨しているのか?

「インラインスタイルは書かないほうが良い」

一度は聞いたことがありますが、何故でしょうか。

  • 記述が重複するから?
  • HTMLとCSSの分離?

もしこれらの理由を尊重したいのであれば、TailwindCSSは不要です。 しかし、現在主流のコンポーネントを使う流れならば、解決するべき問題が違う可能性が高いです。

ReactやVueにおいては、機能的な凝集をコンポーネントという区切りに分けて、それらを組み合わせて開発していきますよね。

特に、記述が重複しているときこそ、コンポーネントによる共通化の出番です。コンポーネントという単位で「機能的に凝集」させていくと、不要な記述の重複を減らしていくことが出来るはずです。また、機能的な凝集において、HTMLとCSSの分離は、一覧性の観点からかえってデメリットとなり得ます。(このあたりは、CSS in JS台頭の大きな理由の1つでもあります)

クラスが多く見た目がごつい?

確かに、コンポーネントで分割するにしても、実装部分には必要なだけユーティリティクラスを並べる必要があります。

こんな感じのイメージですよね。(実際そう)

<div className="w-80 p-1 mt-2 bg-gray-500 shadow rounded border border-gray-700..."

ですが、Viewの実装箇所を見たときに、その表示がどのようになるのかが一行で読み取れるような書き方は他に類を見ません。

以下は、MUIのStackコンポーネントをイメージして書いたものです。

function Stack({children}) {
    return (
        <div className="mt-3 first:mt-0">{children}</div>
    )
}

同様のものをCSS Modulesで書くとしたら、少なくとも以下の記述が必要になります。

import classes from "./path-to-style"

function Stack({children}) {
    return (
        <div className={classes.stack}>{children}</div>
    )
}
.stack:not(:first-child) {
    margin-top: 12px; // テーマによる
}

emotionやStyled Componentsを使ってももう少し長くなるでしょう。

このようなコンポーネントのスタイルを編集/確認したいと感じたとき、CSSの参照箇所を探したりしなければならないと考えると、段々と、インラインは有難いものであるという気持ちになってきませんか?

また、実装部分がコンポーネントだけとは限りません。時には、あるユーティリティクラスの組み合わせのパターンが何度も出現することがあるでしょう。その際は、以下のように、@applyという機能を使えば、CSSクラスと同様に、パターンを共通化することもできます。

h1,h2,h3,p,summary,li,a {
  @apply text-gray-800 dark:text-gray-300 border-gray-500
}

クラスなどのまとまりを作る時に、最終的にCSSプロパティを一つずつ指定していくのは、CSSでも同じことでしょう。

移植性が無い/プリプロセッサが必要?

あなたがもし純粋なHTML、CSS、JavaScriptで仕事をこなしているならば返す言葉もありません。しかし、SassやCSS in JSを使っているならば、同じ言葉を返します。

考えてみると、我々は既に、多くのツールチェインに乗っかっているはずです。

汎用的な要求に応えるプラットフォームに対し、ツールとは、特定の目的を果たす為に、多くの場合必要となる作業を省くために使うものと考えることができます。

Reactが多くの人に使われているのは、UIを宣言的に書くことができ、ステートに対して「リアクティブに」表示が更新されていき、機能や表示を分割することが出来るプログラムを多くの人が望んだからでしょう。

毎度依存が必要になる代償の代わりに、生産性に寄与する多くの恩恵を得られるでしょう。

私はTailwindも同様と考えます。次項で書きますが、Tailwind CSSは、WebのUIのスタイルを指定するにあたり現時点で最適なツールの1つだと考えています。

ユーティリティクラスの名前を覚えるのに抵抗があるならば、今までBootstrapBulmaのクラス名、もしくはMUIのコンポーネントの使い方をドキュメントを見ながら覚えたことを思い出してみましょう。(結局新しいことを覚えるのは大抵のツールにつきまとっているはずです)

確かに、便利だからと言って、再現なくツールを導入していくのは望ましくありません。Create React Appでプロジェクトを作成したらすぐに開発がスタートできる状況は大変好ましいです。望み薄ですが、そのようなテンプレートが公式に対応されれば良いな、と思っています。

(何故かこの項だけ長く書きすぎた💦)

まとめ:Tailwind CSSは、コンポーネントをスタイリングするのに最適な道具の一つである

と、思っています。

多くの場合、Tailwind CSSの欠点と考えられるものが、実は利点である、と考えている為、このように反論していくような書き方を選びました。

アニメーションやトランジションを伴うスタイリングは若干やりづらさを感じますが、Tailwind CSSほど少ない文字数でスタイリングが出来るツールはなかなか無いと思います。

最初は食わず嫌いをしていたものですが、使い始めてから実際に生産性が上がったので、是非とも紹介させていただきたく一筆したためました。

そういえば食わず嫌いと言うと、Vimもハードルが高く感じて使っていなかったりするので、そのうちしっかりと触った上で評価したいですね。

読んでいただきありがとうございます。