ユーティリティファーストCSSのススメ〜なぜ、セマンティックなclass命名は失敗するのか?
見出し画像

ユーティリティファーストCSSのススメ〜なぜ、セマンティックなclass命名は失敗するのか?

菱川拓郎

弊社では全ての新規サイトの構築で、CSSフレームワークをtailwindcssに切り替える意思決定を行い、実際に1年くらいが経過しました。「案件によって、tailwindが向いてそうなものは使う」ではなく「全ての案件で使用」です。使えば使うほどメリットの大きさを感じていますが、同時にtailwindcssの世界観が世間の常識とあまりにも違うため、社内のスタッフには少なからず戸惑いがまだ残っているように思います。

そこで、改めて「なぜtailwindcssを使うと効率的にサイトが構築でき、メンテナンス性が上がるのか」反対に「tailwindcssを使う上で、やってはいけないことは何か」についてまとめたいと思います。

tailwindcssとは

画像1

tailwindcssとは、2020年11月にバージョン2.0がリリースされたばかりの、今注目のCSSフレームワークです。CSSフレームワークといえば、Twitter Bootstrapが有名ですが、tailwindcssはかなり性格が違い、ユーティリティーファーストCSSフレームワークというカテゴリーに入るフレームワークです。

一例として、Bootstrap であれば、ボタンには btn という class が用意されています。

<button type="button" class="btn btn-primary">Primary</button>

btn-primary というクラスはボタンの色を指定していて、仮に btn-danger に変更すると、ボタンが赤色になります。

一方の tailwindcss では、ボタンは次のように記述できます。

<button type="button"
     class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
 Button text
</button>

初めて見た方は、「いやclass、多っ!」と思わず突っ込んでしまうかと思います。17個もついてますね。それぞれの class は、それぞれほぼひとつのCSSプロパティと対応しています。

.inline-flex {
  display: inline-flex;
}
.font-medium {
  font-weight: 500;
}
.px-4 {
  padding-left: 1rem;
  padding-right: 1rem;
}

長くWeb制作に関わってきた人ほど、「これの一体どこが効率的なのか?」と訝しむのではないかと思います。また、パディングを指定するための .px-4 などは、「典型的なダメなCSS」と教えられてきたために、生理的な嫌悪感を感じる方すらいるかと思います。

かくいう私も、最初は抵抗感がありました。しかし、この「典型的なダメCSS」が、GitHub、Heroku、Twitchなど様々な大規模サイトで利用され、注目を集めているのです。それはなぜなのでしょうか。

「ベストプラクティス」は、実際には役に立たない。

tailwindcssのトップページに、tailwindcssの作者の言葉として大きく掲げられている言葉です。かつてベストプラクティスであると信じられてきた「セマンティックなclass名」が、CSSのメンテナンスを困難にし、あなたのCSSファイルを信頼できないものにしてきたのではないか、と問いかけています。

この問いかけだけでも、心当たりがいくつもある方はいらっしゃるのではないでしょうか?CSSファイルは時として長大になり、長大になったCSSファイルは簡単にアンタッチャブルな存在になります。他人が作ったサイトのメンテナンスを引き継いだことがある方で、既存のCSSの記述を全て精査すると言う方がどれだけいるでしょうか。多くの場合「既存のCSSはちょっとでも触ると、どこに影響するか分からないのでとりあえずそのまま置いておいて、今回の改修で必要なCSSは全部新しく書こう」となるのではないでしょうか?

この問題は、詰まるところHTMLとCSSが別ファイルになっていることが根本的な原因です。CSSが生まれる前の太古の時代は、HTMLの中にスタイルも書いてあるのが当たり前でした。この方式は当然ながら、デザイン変更に弱い。HTMLファイルが100あれば、100ファイル全て変更しなければいけなかった。HTMLとCSSを分けることで、HTMLファイルには一切手を加えずに、CSSを変更するだけでサイト全体のデザインを変更できるようになったのです。

しかし、一方でファイルが分かれたことは別の原罪を生みました。CSSファイル内の記述が、HTMLのどこで使われているのかが分からないからこそ、「うかつに消せない問題」が発生するのです。もちろん、その問題を解決するために導入されたのが「セマンティックな命名規則」と言うことになるのでしょう。

なぜ class 名を考えるのにこんなに時間を使っているんだろう

セマンティックな class 名とは、乱暴に言ってしまえば、「名前からサイト上のUIが思い浮かぶ class 名」と言うことだと思います。.px-4 のような class 名を導入してしまうと、この class を実際のサイトで使っているかどうかを、名前から類推するのは不可能です。しかし、 .btn と言う class 名であれば、少なくともサイトでボタンが1個でもあれば、使っているのは確実でしょう。なるほど、意味が通る名前にした方が、何かと便利そうです。

しかし、ものごとはそううまく行きません。例えば、顔写真、名前、短いbioと言うパーツがあり、 .profile と言う class 名をつけたとしましょう。しかし、コーディングを進めるうちに、全く同じデザインで、サムネイル画像、ブログ記事のタイトル、短い説明文と言うパーツをデザイン上に見つけてしまいました。あなたは両方に共通して使えるような class 名を考えますか?それともCSSの記述をコピーして .profile と .blog-post の2つを作りますか?もしくは、諦めてブログ記事に .profile を使いますか?

コーディングに慣れてくればくるほど、時間と脳のリソースを「class名を何にするか」に使いすぎているのではないかと言う疑問を抱く人は少なくないはずです。そのclass名を目にするのは、将来の自分自身か、自分のサイトを引き継いだ誰かか、ソースコードをチェックする酔狂なWeb制作者(他人)だけです。.profile にするか .blog-post にするか .card にするか、その悩みに一体どれだけの実益があるのでしょうか。

CSSの仕様は実際、難解すぎる。

CSSには詳細度と言う便利ですが、おそらく多くのWeb制作者が正しく理解していない仕様があります。ざっくり言うとCSSプロパティが重複したときに、どちらを優先するかと言う仕様です。

<div id="blue" class="red">Color?</div>

#blue {
  color: blue;
}
.red {
  color: red;
}

このように片方は青、もう片方は赤、と言う矛盾する指定があった場合に、どちらを優先するか。classよりもidが優先されると言うのは、idがHTMLファイルの中で一つしか許されない特別なものであるので、納得しやすい。

しかし、次の記述で、どちらの色になるか、自信を持って答えられますか?

<div class="blue">
  <p class="red">Color?</p>
</div>

.blue p {
  color: blue;
}
p.red {
  color: red;
}

下記はCSSの詳細度を分かりやすくまとめた表ですが、余計に混乱しそう…。

画像2

そこで、BEMのようなCSS命名規則は、ひとつのclass名を長くして、詳細度の計算を避けようとします。

<div class="profile__person-name__large__is-pro-user"></div>

果たして、この class 名は正しいのか、正しくないのか。

諦めよう、全てを。
そしてようこそ、ユーティリティファーストCSSの世界へ。

結局、CSSとHTMLを分離しようと言う様々な試みは、個人的には全てうまくいっていないし、うまくいっていると言う人がいれば、その人がよほどスーパーマンだと言うことにしか思えません。ひとりのWeb制作者としては、高みを目指すのは良いことと言えるでしょう。しかし、私は経営者でもあり、経営者にとってスーパーマンがいないと成り立たない制作フローほど恐ろしいものはありません。

CSSは人類には早すぎたのです。残念ながら、使いこなせるようなものではなかった。CSSはメンテナンスが大変なので、CSSをメンテナンスすることをやめよう。シンプルな考え方だと思いませんか?

一方、HTMLは分かりやすく、メンテナンスがしやすい。様々なツールが生まれたいま、100ページあるサイトだからといって、100ファイルのHTMLを全て手で書いている人がいるでしょうか?(昔は、いました。驚くべきことに)現代ではほとんどの場合、サイトの運営には何らかのビルドツールを使っているか、CMSを利用しており、全てのHTMLファイルに関連する変更が発生したとしても、即座に適用できます。

だから、CSSを書くのはやめましょう。tailwindcssを使えば、ほとんど全てのCSSプロパティに対応するclassがあらかじめ用意されていますので、CSSファイルをエディタで開くことはほとんどありません。HTMLだけに集中できます。CSSファイルを変更しないからこそ、うっかり書き換えちゃうと他のページに影響が出ちゃうかも…と心配することもなくなります。class名を考える時間もすっきり、なくなります。詳細度について考える必要もありません。自由だ!俺は自由なんだ!

インラインCSSと何が違うのか?

メリットは分かったが、それならCSSファイルを使うこと自体をやめても同じなのでは?と思うかもしれません。インラインCSSを書くのと何が違うのか。実は、ここにtailwindcssがフレームワークたる由縁があります。

インラインCSSでは、実際あらゆる値を記述することが可能です。

<div style="margin-top: 21px"></div>
<div style="margin-top: 2em"></div>

この状態でデザインに統一感を持たせるのは、さすがに厳しいですよね。一方、用意されたclassを使う方法であれば「用意された中でどれを使うか」と言う選択になります。

<div class="mt-4"></div>
<div class="mt-8"></div>

例えば余白については、px単位で指定されることがなくなりますし、また単位が混在することも避けられます。結果的に、サイトデザインの統一性に寄与します。これは余白だけでなく、色についてもあらかじめ用意されたカラーパレットからの選択に制限できますし、利用できるフォントファミリーも制限できます。CSSフレームワークの機能としては、本来これで十分だったと言うことです。

Bootstrapと何が違うのか?

ちょっと待って。CSSを書きたくないなら、Bootstrapを使うのでも変わらないのでは?と疑問に感じる方もいるでしょう。その通りです。

しかし、Bootstrapはあらゆるパーツを網羅しているわけではなく、あくまでよく使われるUIパーツが用意してあるにすぎません。そこにないものは、結局自分でCSSを書くしかない。

tailwindcss は、ほとんどCSSそのものと言っても良いほどなので、あらゆるデザインで使えます。Bootstrap を使うときに起こるようなBootstrap臭さが残ると言うようなことがありません。デザイン性を重視するプロジェクトにおいては非常に重要なメリットです。

不要なclassがたくさんあるのは、逆に無駄なのでは?

ひとつのサイトで全てのCSSプロパティを使用することがないように、tailwindcssで用意されている豊富なclassの全てを使用するプロジェクトはありません。となると、1回も使っていないclassが書かれたCSSをユーザーにダウンロードさせることになってしまうのでは?と心配になるかもしれません。

しかし、これについても現代の制作環境が解決します。tailwindcssでは、PurgeCSSと言うライブラリを使用することで、HTMLのなかで一度も使われていないCSSの記述はビルド時に削除します。また、圧縮も行いますので、怖くて消していない記述がたくさんあるCSSファイルを配信するよりは、よほど無駄が少ないと言えるでしょう。

ユーティリティーファーストCSSを使いこなすうえで、やってはいけないこととは?

とにかく、CSSを書くのがやってはいけないことです。CSSを書くことによるデメリットからの脱却がメリットなのですから、その最大のメリットを捨ててしまっては本末転倒です。違和感はあるでしょうが、classをたくさんHTMLに書いてください。

また、用意されたclassで適用されるCSSプロパティの値は、設定ファイルでコントロールできます。使いたい色が用意されてなかった?ブレイクポイントを変更したい?それでもCSSは書かないでください。設定ファイルで対応可能です。

// tailwind.config.js
module.exports = {
   theme: {
       colors: {
           blue: {
               light: '#85d7ff',
               DEFAULT: '#1fb6ff',
               dark: '#009eeb',
           }
       },
       screens: {
           'sm': '640px',
           'md': '768px',
           'lg': '1024px',
           'xl': '1280px',
           '2xl': '1536px',
       }
   }
}

原則は分かった。でも使いこなせる気がしない!

分かります、実際CSSを記述する制作スタイルに慣れきってしまうと、CSSを書くなと言われても、どうやったらいいのか途方に暮れることと思います。

そんな時のために、tailwind uiと言うプロジェクトが用意されています。tailwindcssを使って、実際のUIを組んでみたサンプル集のような感じですね。

画像3

有料にはなりますが、なくてはならない必需品で、制作のお供に常に参考にしながら進めることができます。

まとめ

いかがでしょうか。tailwindcssを使ってみたくなりましたか?

実際には細かい使い勝手の悪さとか、もっとこう言うものも用意されていたらいいのにと言う希望はあるものの、人気の高さが手伝ってか、非常にハイスピードで熱量高くアップデートが行われています。

また、tailwindcssには膨大な数のclassが存在し、その全てを覚えることはできません。IDEのサジェスト機能は非常に重要になります。今後、そう言った実際の使用感についてもご紹介できればと思います。


この記事が気に入ったら、サポートをしてみませんか?
気軽にクリエイターの支援と、記事のオススメができます!
菱川拓郎

サポートは連載継続のはげみになります!

お読みいただきありがとうございます!
菱川拓郎
コンクリートファイブジャパン株式会社代表取締役。「世界を相手に戦う日本企業をサポートする」をミッションに、concrete5を中心に様々なサービスの提供を行う。近著に『世界一わかりやすい concrete5導入とサイト制作の教科書』(技術評論社)など。