こんにちは!8年前に、Tailwindを発見して興奮しながら書いた記事があります。

当時、私はCSSコードの構造化方法を全く知らず、完全な混沌とした状態とTailwindのどちらかを選ぶなら、Tailwindを選んで本当に嬉しかったです。それが多くの小さなサイトを作るのに役立ちました!

先週くらい、2つのサイトをTailwindから、よりセマンティックなHTML + バニラCSSに移行する作業を行い、とても楽しくてとても興味深かったので、ここで学んだことをいくつか紹介します!

いつものように、私はフルタイムのフロントエンド開発者ではないので、CSSの学習は長年にわたって断続的に行われてきました。

Tailwindは意外と多くのことを教えてくれた

CSSの構造化について考え始めたとき、最初は怖気づきました。私はCSSの構造化があまり得意ではないからです!しかし、CSSの構造化方法について書かれたブログ記事(A whole cascade of layersHow I write CSS in 2024など)を読んでいくうちに、いくつかのことに気づきました。

  1. CSSコードベースにはさまざまな要素(レイアウト!フォント!色!共通コンポーネント!)がたくさん存在する
  2. それらの要素を管理するためのシステムやガイドラインを持つことは非常に有用で、そうしないと混沌とした状態に陥る
  3. Tailwindにはその一部に対するシステムがあり、私はすでにそれらのシステムを知っている!気に入ったシステムを真似できるかもしれない!

たとえば、Tailwindには以下があります。

これから話すシステム

私のCSSコードベースのいくつかの側面と、それぞれにどのようなルールを課したいかについて、これまでの考えをいくつか紹介します。その中にはTailwindからコピーしたものと、そうでないものがあります。

  1. リセット
  2. コンポーネント
  3. フォントサイズ
  4. ユーティリティクラス
  5. ベース
  6. スペーシング
  7. レスポンシブデザイン
  8. ビルドシステム

1. リセット

tailwind.cssを開いて最初の200行程度をコピーすることで、Tailwindの「preflight styles」をそのままコピーしました。

私は時間の経過とともにTailwindのCSSリセットとの関係を築いてきたことに気づきました。たとえば、Tailwindはすべての要素にbox-sizing: border-boxを設定します(これは要素の幅にパディングが含まれることを意味します)。

* { box-sizing: border-box; }

これなしでCSSを書くのは私にとって本当に調整が必要で、Tailwindのリセットには他にもhtml {line-height: 1.5;}のように、私が無意識に使っていてその存在すら気づいていないものがたくさんあると思います。

2. コンポーネント

この次の部分がCSSの大部分を占めます!

ここでのアイデアは、VueやReactのコンポーネントに関連する精神で、「コンポーネント」ごとにCSSを整理することです。(ただし、サイトにJavaScriptが一切含まれていない場合もあります)

基本的なアイデアは次のとおりです。

  1. 各「コンポーネント」には一意のクラスがある
  2. あるコンポーネントのCSSは、他のコンポーネントのCSSを上書きしない
  3. 各コンポーネントには独自のCSSファイルがある

したがって、あるコンポーネントのCSSを編集しても、他のコンポーネントの何かが不思議に壊れることはありません。また、私が実際に変更したいCSSの80%程度はさまざまなコンポーネントファイルにあるため、100行のコンポーネントを編集する場合、その100行だけを考えればよいのです。私にとってははるかに考えやすくなります。

たとえば、このHTMLは.zine「コンポーネント」かもしれません。

<figure class="zine horizontal">
    <img src="whatever.jpg">
</figure>

そしてCSSは、ネストされたセレクタを使って次のようになります。

.zine {
  ...
  &.horizontal {
    ...
  }
  &.vertical {
    ...
  }
  &:hover {
    ...
  }
}

コンポーネント同士が干渉しないことを保証するプログラム的なもの(Web Componentsや@scopeなど)は何もしていませんが、単に規約を持ち、できる限り努力するだけで、大きな改善のように感じられます。

次に、サイト全体で一貫性を維持し、これらのコンポーネントを互いに整合させるための規約についてです!

3. 色

colours.cssには、必要に応じて使用できる次のような変数がたくさんあります。色は本当に難しく、このリファクタリングで色の使い方を再検討したくなかったので、この部分はそのままにしました。

ここで適用しようとしている唯一のガイドラインは、サイトで使用されるすべての色がこのファイルに記載されていることです。

:root {
  --pink: #fea0c2;
  --pink-light: #F9B9B9;
  --red: #f91a55;
  --orange: rgb(222, 117, 31);
  ...
}

4. フォントサイズ

Tailwindで気に入っていた点の1つは、フォントサイズを設定したい場合、「テキストを大きくしたいな」と思ってtext-lgと書くだけで済むことでした!そして、十分に大きくない場合は、代わりにxl2xlを使えばよいのです。empxremのどちらを使っているかを覚えておく必要はありません。

そこで、Tailwindから取った次のような変数をいくつか定義しました。

  --size-xs: 0.75rem;
  --line-height-xs: 1rem;

  --size-sm: 0.875rem;
  --line-height-sm: 1.25rem;

そして、フォントサイズを設定したい場合は、次のようにします。Tailwindより少し冗長ですが、今のところこれで満足しています。

h3 {
  font-size: var(--size-lg);
  line-height: var(--line-height-lg);
}

5. ユーティリティ

多くの異なるコンポーネントに登場するボタンのようなものがあります。私はこれらを「ユーティリティ」と呼んでいます。

Tailwindからいくつかのユーティリティクラス(スクリーンリーダーのユーザーだけに表示されるべきもののための.sr-onlyなど)をコピーしました。

このセクションはかなり小さく、ここでの変更には注意を払うようにしています。

6. ベース

「ベース」スタイルは、自分で選択したサイト全体に適用されるスタイルです。私はサイト全体に多くのスタイルを適用することに自信がないので、このセクションは本当に小さく保つ必要があります。現在、私が大丈夫だと感じているのはこの2つだけで、<section>のものは変更するかもしれません。

/* put a 950px column in the middle of each <section> */
section {
  --inner-width: 950px;
  padding: 3rem max(1rem, (100% - var(--inner-width))/2);
}

a {
  color: var(--orange);
}

ベーススタイルについては、ほぼ何もない状態から始めて、共通のものを特定したらコンポーネントからベーススタイルにスタイルを移動していく、というボトムアップの作業が一番やりやすいと思います。

7. スペーシング

パディングとマージンの管理方法については、まだ完全に解決していません。Tailwindでやっていたように、望む見た目になるまでパディングとマージンをあちこちに無計画に配置するよりも、確実に原則に基づいた方法を目指しています。

現在、外側のレイアウトコンポーネントができるだけスペーシングを担当する方向で進めています。たとえば、子要素の間にスペースを空けたい<section>がある場合、子要素を均等に配置するために次のようなものを使うかもしれません。

section > *+* {
  margin-top: 1rem;
}

参考になったブログ記事。

8. レスポンシブデザイン:グリッドをもっと活用しよう!

Tailwindでレスポンシブデザインをしていた方法は、多くのメディアクエリを使うことでした。Tailwindにはmd:text-xlという構文があり、これは「md以上のサイズでtext-xlスタイルを適用する」という意味です。

今はかなり異なるアプローチを試みていて、ブレークポイントをそれほど必要としない、より柔軟なCSSグリッドレイアウトを作るようにしています。これは難しいですが、グリッドで何が可能かを学ぶのは本当に興味深いことで、Tailwindではできないことの良い例だと思います。

たとえば、auto-fitを使って、大画面では2列、小画面では1列を自動的に使用する方法を学んでいます。

  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 400px), max-content));
  justify-content: center;

また、grid-template-areasもたくさん使いました。これはTailwindでは使えない素晴らしい機能です。

参考。

9. ビルドシステム:esbuild

開発中は、ビルドシステムは必要ありません。CSSには現在、次のような組み込みのimport文があります。

@import "reset.css";
@import "typography.css";
@import "colors.css";

また、次のような組み込みのネストされたセレクタもあります。

.page {
  h2 { ...}
}

必要に応じて、esbuildを使って本番用のCSSファイルをバンドルできます。次のようになります。

esbuild style.css --bundle --loader:.svg=dataurl  --loader:.woff2=file --outfile=/tmp/out.css

通常はCSSやJSのビルドシステムを避けていますが、esbuild(2021年にここに書きました)はWeb標準に基づいており、静的なGoバイナリなので、使用しても問題ありません。

Tailwindから移行する理由

Tailwindから移行した理由を尋ねる人が何人かいました。寄与した要因はいくつかあります。

  • Tailwindは2018年以降、ビルドシステムへの依存度が高まっており、新しいバージョンのTailwindをビルドシステムなしで使うことは不可能(?)だと思います。そのため、私は長年Tailwind v2を使ってきました。(litewindもあるようです)
  • Tailwindは常にビルドシステムと一緒に使うことが前提でしたが、私はそれをやったことがないので、多くのプロジェクトに2.8MBのtailwind.min.cssファイル(270K gzipped)があり、少し馬鹿げていると感じます。
  • Tailwindを使い始めたときより、CSSがかなり上手くなりました
  • 最終的にTailwindには制限があります。CSSで奇妙なことをしたい場合、Tailwindでは常に可能とは限りません。それらの制限は非常に有用な場合があります(この記事の多くは、Tailwindの制限の一部を再実装することについてです!)が、現時点では自分で選んで選びたいと思います。
  • 同じプロジェクトでバニラCSSとTailwindを混在させたサイトができてしまい、メンテナンスが楽しくありませんでした
  • よりセマンティックなHTMLを書くのがどのような感じかを知りたくなりました。

気になっているCSS機能

この作業を通じて、使用しなかったもののいずれか学びたいと思っているCSS機能をたくさん知りました。

Tailwindから離れたもう一つの理由

この記事では、Tailwindを使って学んだことについてたくさん話してきましたが、それはすべて本当です。

しかし、3年前に読んだTailwind and the Femininity of CSSという記事が、私の心に深く残りました。おそらく、私は最初にその記事が説明しているようなCSSに対する態度を持っていたと思います。

彼らはそれが簡単だと聞いているので、簡単だと仮定します。しかし、実際に使ってみるとうまくいきません。言語のせいに違いない、なぜなら彼らは自分が賢いことを知っていて、これは簡単なはずだからです。

しかし、過去10年間で、私はCSSを技術として本当に愛し、尊重することを学びました。

そこで何年も前に、「CSSは難しい」という反応に対して、CSSを上達させ、技術として真剣に取り組むことで対応したいと決めました。それによってすべてが変わりました。私は多くの不満(「センタリングは不可能」)がCSSではずっと前に解決されていたことを学び、また「センタリング」とは何かが常に単純ではなく、多くの方法があるのは理にかなっていることも理解しました。CSSが難しいのは、難しい問題を解決しているからなのです!

過去10〜15年間に構築された新しいCSS機能(この記事でいくつか触れました!)と、それがCSSを使いやすくしていることに、私は非常に感心しています。そして、CSSスキルを向上させるために費やした時間は、本当に素晴らしい経験でした。

そしてその記事は、TailwindがCSSの専門知識の価値を下げることに寄与しており、私自身にとっては有用なツールであったとしても、その一部になりたくないと感じさせました。特にLLMの時代において、人間の専門知識を評価することがこれまで以上に重要に感じられる中で。

私に影響を与えたTailwindを批判するもう一つのブログ記事。

今回はこれで終わり!

wizardzines.comのCSSを最初に設計・執筆してくれたMelody Starlingに感謝します。サイトのすべてクールで楽しい部分は、Melodyのおかげです。

また、この作業中にCSS TricksSmashing Magazineなどから、素晴らしいCSSに関するブログ記事をたくさん読みました。この記事を通じてその一部をリンクしようとしました。CSSコミュニティの人々が自分の実践を共有してくれていることに、本当に感謝しています。