構築・運用を楽にする Tailwind CSS 入門 ~導入からカスタム設定まで~

はじめに

webサイト構築において、HTML/CSS を担当するフロントエンド開発者が直面する大きな課題の一つが「CSS設計」です。

基本的に CSS はグローバルスコープであり、無計画にコードを追加してしまうと、
意図しない上書きが起こってしまう(ヘタをすれば発見されずリリースされてしまう)。
または、既存の CSS との干渉により詳細度を上げて上書きをせざるを得なくなる(詳細度のパワーインフレ)。

つまり CSS には「破綻しやすい」という特徴があるため、リリース後に触れば触るほどに CSS の寿命は縮まります。
そうして違法建築状態となった CSS は、webサイトの更新工数を増加させ、巡り巡ってwebサイトの寿命を縮めることに繋がります。

これに対処するため、MindBEMding、OOCSS、SMACSS、FLOCSSなど、様々な CSS設計手法が考案されてきました。

ちなみに、弊社の新規プロジェクトでは FLOCSS が採用されることがほとんどです。

上記のCSS設計手法はいずれも「class の命名ルールでスタイルの適用範囲を絞り込もう」というアプローチです。
このため、CSS設計の難しさとは、実質的には class 命名の難しさと言っても過言ではないでしょう。

そこで、この記事で紹介するのは class の命名に悩んだり、CSSファイルを触ったりする必要なく、ユーティリティクラスの組み合わせによりデザインを実現する Tailwind CSS というフレームワークです。

Tailwind CSS を活用することで、開発の迅速化やメンテナンスの容易さなど、より良い成果を生み出すことが期待できます。CSS設計の手法の一つとして興味を持っていただければと思います。

Tailwind CSS の特徴

  • HTML側の編集のみで、CSSファイルに必要なスタイルが追加されていく
  • 使われている class だけが CSS に追加されるため、必要以上のユーティリティクラスが生成されず CSS の肥大化が発生しにくい
  • 任意値の指定、子要素への指定、レスポンシブ対応、擬似要素、擬似クラスにも対応できるため、CSSファイルを編集するのと同様にスタイルをあてられる

以上のような特徴があります。

この記事では、非エンジニアでも Tailwind CSS を扱えるよう、
導入方法から使用方法までを紹介します。

この記事で扱うこと

  • Tailwind CSS 導入のメリットとデメリット
  • Tailwind CSS によるコーディング例
  • HTML/CSS のみのシンプルな環境構築
  • tailwind.config.js への設定の記述方法

この記事で扱わないこと

  • ユーティリティファーストでの設計手法
  • Sass環境への Tailwind CSS の導入
  • apply など 発展的な使い方
  • React/Vue などと Tailwind CSS の組み合わせ

この記事は以下のような人を対象にしています

  • Tailwind CSS を扱ったことがない人
  • webサイトの更新の際、CSSの編集作業をできる限り避けたい人
  • 素の HTMLファイル を触ってwebサイトの更新作業をする人
  • class の命名に疲れた人

なお、この記事では、素の HTMLファイルを扱うプロジェクトへ Tailwind CSS を導入する方法を解説します。
React / Vue のような、コンポーネントベースのフレームワークで使うべきといった話や、
他の CSS と混在させると危険など、いろいろな捉え方や考え方はあるかと思いますが、今回は一度脇に置いておいてください。
普通の MPA での話がメインです。

Tailwind CSS を使うコード

それでは早速、Tailwind CSS を使用したコードを紹介してみたいと思います。
ボタンを作って比較してみましょう。

See the Pen usual by takemoto-rs (@takemoto-rs) on CodePen.

こちらは特に説明の必要もないと思います。

Tailwind CSS を使った記述

See the Pen Tailwind Sample by takemoto-rs (@takemoto-rs) on CodePen.

こんなコードになりました。
CSS を記述せずに済んでいますが、代わりに HTML がとても長くなっています。

コード解説

それでは Tailwind CSS で組んだ上記のコードの中で、Tailwind CSS の特徴とも言えるものをピックアップして解説します。

  • hover: : 擬似クラス :hover
  • after: : 擬似要素 ::after
  • md:lg: : レスポンシブ対応(ブレイクポイント)
  • [.25em] : []で囲むことで、Tailwind CSSで事前に定義されていない任意値の使用
  • [&>span]: : 子要素へのスタイルの定義
  • clip-pathは未対応プロパティですが [clip-path:polygon(0_0,0_100%,100%_50%)] とすれば実現可能です

text-white だとか font-bold だとかは解説せずともなんとなくわかると思いますので、解説は割愛します。

このように Tailwind CSS を使うことで、CSSファイルを編集せずとも HTML ファイルの編集のみで、ほぼ全てのスタイルが実装できるようになります。

Tailwind CSS のこれらの機能は、Tailwind Play で体験することが可能です。

デメリット

上記コードではあえてプロパティを多めに作ってみました。
このように、HTML の class の記述量が多くなってしまいます。
この冗長な記述こそ Tailwind CSS の採用がためらわれる大きな要因かと思います。

しかし、Tailwind CSS をメインとして使う開発者は口を揃えて「慣れる」と言いますし、
Tailwind CSS の活用方法次第で、class の記述量を気にならない範囲内に留めることも可能です。

例えば、React や Vue のように初めからコンポーネント単位で分割するものであれば一か所に記述を集約できますし、EJS であれば、変数化したりコンポーネントを include 化することで集約することも可能です。

弊社のように FLOCSS を採用することが多いのであれば、ユーティリティクラスだけを Tailwind CSS に任せ、ユーティリティクラスの記述量を最低限に留めることも可能です。

Tailwind CSS で得られるメリット

コーディングの際、以下のような経験をしてきた人も多いのではないでしょうか。

「なぜかここだけ余白が違う・・・」
「なぜかここだけイレギュラーなレイアウト・・・」
「運用フェーズに入ってデザインルールが守られなくなってきた・・・」
「ここにテキストを一文いれたいけど、そのためだけに CSS を書かないといけない・・・」
「class 名もう思いつかない・・・」
「この class 外しても大丈夫なのかな・・・?」

Tailwind CSS の使用によりこれらの悩みから解放されます。

class の記述が冗長になるというデメリットを差し引いても、Tailwind CSS を採用することで得られるメリットは余りあるものでしょう。

導入してみましょう

Tailwind CSS を使用するには、まずCSSのビルド環境があることが前提となります。
CDNも用意されていますがファイルサイズが非常に大きいので、決して本番環境には使わないでください。
公式にも本番環境には適していないことが明記されています。

https://tailwindcss.com/docs/installation/play-cdn

それでは以下のようなHTMLファイルとCSSファイルのみで構成される、最もシンプルな CSS ビルド環境を作ってみましょう。

├─ dist
│     └─ html
│           ├─ index.html
│           └─ css
│                └─ styles.css // 出力されるCSS
└─ src
      └─ css
            └─ styles.css // ソース側CSS

あくまでサンプルですので、最低限の記述に留めます。

※ Node.js がインストールされてなければ以下から、LTS版をインストールしてください。
https://nodejs.org/en

Tailwind CSS を 導入する上でもっとも手軽なのが npm-scripts です。
gulp webpack Vite PostCSS などもありますが、ここでは npm-scripts での導入方法を紹介します。

1. 必要パッケージのインストール

開発環境のルートとなるディレクトリでターミナルを開き、以下のコマンドを叩く。

npm i -D tailwindcss

ちなみに、VS Codeのような IDE を使っていない人向けに書きますが、
Windows の場合、対象となるディレクトリを エクスプローラーで開いて、

スクリーンショット:Windows のエクスプローラーのアドレス欄に cmd と入力されている

アドレス欄に画像のようにcmdと入力して Enter を ッターン!することで、コマンドプロンプトが、そのディレクトリをカレントディレクトリとした状態で開きます。
powershell でも可能です(黒い画面が怖い人も Powershell なら安心ですね!)。

ちなみに私はcdコマンドなんて、めったに使いません。

2. tailwind.config.js の作成

tailwind.config.jsファイルを作成・編集し、対象となる HTML ファイルへのパスを設定します。これにより、Tailwind CSS は 指定した HTMLファイル内で使用されている class を識別できるようになります。

npx tailwindcss init

上記コマンドを叩くと、以下のようなファイルが作成されると思います。

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [],
  theme: {
    extend: {},
  },
  plugins: [],
}

3.npm scriptの設定

次にパッケージのインストール時に作成された package.json を編集します。

{
  "scripts": {
    "build": "tailwindcss -i ./src/css/styles.css -o ./dist/html/css/styles.css",
    "watch": "npm run build -- --watch"
  },
  "devDependencies": {
    "tailwindcss": "^3.4.1"
  }
}

4. ソース側 CSS にディレクティブを記述

公式ドキュメントでは以下のように記述するよう書かれています。

@tailwind base; /* 入れたほうがよい */
@tailwind components; /* 正直あってもなくてもよい */
@tailwind utilities; /* 必須 */

この点に関しては、カスタマイズの項目で補足します。

5. 開発の開始

npm run watch

HTML ファイルに 以下のように記述してみてください。

<div class="text-red-700">Hello Tailwind CSS</div>

ビルドプロセスが走れば出力側の CSS ファイルの下部に以下のように追記されていると思います。

.text-red-700: {
    color: rgb(185 28 28 / var(--tw-text-opacity));
}

他の class も追記してみてください。CSSファイルにスタイルが追記されていくことがわかると思います。
これで Tailwind CSS の導入が完了しました。

Tailwind CSS のカスタマイズ

Tailwind CSS は カラー設定、フォントサイズ、余白、ブレイクポイントなどにおいて、デフォルトの設定値をもっており、そのままではプロジェクトに導入しづらい面もあります。

例えば、フォントサイズとブレイクポイントのデフォルト値は、以下のようになっています。

.text-sm {
  font-size: 0.875rem; /* 14px */
  line-height: 1.25rem;
}

.text-base {
  font-size: 1rem; /* 16px */
  line-height: 1.5rem;
}

.text-lg {
  font-size: 1.125rem; /* 18px */
  line-height: 1.75rem;
}
// sm:	640px
@media (min-width: 640px) { ... }
// md:	768px
@media (min-width: 768px) { ... }
// lg:	1024px
@media (min-width: 1024px) { ... }
// xl:	1280px
@media (min-width: 1280px) { ... }
// 2xl:	1536px
@media (min-width: 1536px) { ... }

ブレイクポイントの値はプロジェクトによって変わるでしょう。

賛否がわかれますが、コーディング規約で :root の font-size を 62.5% とすることもあるでしょう。

作業工程の関係上デスクトップファーストで進めざるを得ないこともあると思います。

使用カラーについても当然、プロジェクトによって変更が必要です。

Tailwind CSS では tailwind.config.js というファイルを編集することで設定値を、プロジェクトに応じた値に変更することが可能です。

実際の変更例

tailwind.config.js の以下の箇所に追記していきます。

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ['dist/**/*.html'],
  theme: {
    // ここに書くと上書き
    extend: {
      // ここに書くと追加
    },
  },
  plugins: [],
}

theme 直下に記述することで、既存の設定値を上書きし、
extend 内部に記述することで、既存の設定値に追加されます。

カラー設定の変更

theme: {
  colors: {
    'red-800': '#da442a',
    'red-700': '#e47a67',
    'blue-800': '#2a4ada',
    'blue-700': '#677ee4',
    'gray': '#333333',
    // 以下略

カラー設定については、ブランドカラーなどの指定は必須でしょう。
デフォルトで200色以上用意されていますが、エディタの補完機能が鬱陶しくなるだけなので、私は theme 直下に記述します。実際にはもう少し細かく設定すると思います。

参考:公式ドキュメント
https://tailwindcss.com/docs/customizing-colors

ブレイクポイント

theme: {
  screens: {
    xl: '1200px',
    lg: '992px',
    md: '768px',
    sm: '576px',
    // 以下略

このように記述することで、ブレイクポイントの値の変更も可能です。

ちなみに、デスクトップファーストの記述にしたい場合は、以下のように記述します。

theme: {
  screens: {
    xl: {
      max: '1200px',
    },
    lg: {
      max: '992px',
    },
    md: {
      max: '768px',
    },
    sm: {
      max: '576px',
    },
    // 以下略

参考:公式ドキュメント
https://tailwindcss.com/docs/responsive-design#customizing-your-theme

フォントサイズ

theme: {
  fontSize: {
    xs: '1rem',
    sm: '1.2rem',
    base: '1.4rem',
    lg: '1.6rem',
    xl: '1.8rem',
    '2xl': '2.4rem',
    '3xl': '3.2rem',
    // 以下略

フォントサイズについては、このように設定できます。

参考:公式ドキュメント
https://tailwindcss.com/docs/font-size#customizing-your-theme

ただし、このままでは :root の font-size を 62.5% としていた場合、
.text-xs は 16px相当になります。

なぜなら ソース側 CSS の、下記ディレクティブ記述が、Preflight という、独自のリセットCSSを出力しており、そこで :root の font-size を100% としているからです。

@tailwind base;

Preflightのコードは Tailwind CSS のリポジトリで確認できます。

https://github.com/tailwindlabs/tailwindcss/blob/master/src/css/preflight.css

手になじんだ リセットCSS を使用したいこともあると思いますので、
この記述をなくしてしまってもよいのですが、
なくしてしまうと、Tailwind CSS 独自のカスタムプロパティも生成されないため、translate などの
一部プロパティが使えなくなってしまうといった弊害もあります。

そこで以下のように tailwind.config.js を編集します。

corePlugins: {
  preflight: false,
},
theme: {
  fontSize: {
    xs: '1rem',
    sm: '1.2rem',
    base: '1.4rem',
    lg: '1.6rem',
    xl: '1.8rem',
    '2xl': '2.4rem',
    '3xl': '3.2rem',
    // 以下略

このように記述することで、Tailwind CSS のカスタムプロパティは残しつつ Preflight をカットすることが可能です。
ただし、Tailwind CSS の設計思想という原則に従うのであれば、こういった手法を使わず
1rem = 16px
で構築すべきでしょう。

tailwind base に関する補足説明

上述のように、既存の CSS に新たに Tailwind CSS を導入する場合、
Preflight の優先順位を意図的に下げたいですね。

私は既存の CSS がある場合、以下のようにします。

@layer reset {
  // リセット系CSS の記述 
}

@layer default {
  // プロジェクトの基本設定(FLOCSS では base に相当)
}

// その他のスタイル

@layer default { // reset でも可
  @tailwind base;
}
@tailwind components;
@tailwind utilities;

このようにすることで、記述位置に関わらず、Preflight の 優先順位を下げることが可能です。

ちなみに、Tailwind CSS を使用する場合、カスケードレイヤーのレイヤー名に
base components utilities
の使用は注意が必要です。
これらは、Tailwind CSS が、上で挙げたレイヤー名を使用するため、意図しない挙動となる恐れがあります。

余白設定

さらに余白設定を変更してみます。
ちなみに初期状態では以下のようになります。

.mt-1 {
  margin-top: 0.25rem; /* 4px */
}

.mt-2 {
  margin-top: 0.5rem; /* 8px */
}

.mt-3 {
  margin-top: 0.75rem; /* 12px */
}

これは Bootstrap も同様なのですが、直感的ではないと思いませんか?
私は Bootstrap で、この余白設定を見たときブラウザをそっと閉じました。

この記事では「個人の技量に関わらず扱いやすくすること」を目的としていますので、遠慮なく書き換えます。

theme: {
  spacing: {
    0: '0',
    1: '1px',
    2: '2px',
    3: '3px',
    4: '4px',
    5: '5px',
    6: '6px',
    7: '7px',
    8: '8px',
    9: '9px',
    // 以下略
.mt-5 {
  margin-top: 5px;
}

このようにpxに変更することも可能ですが、Tailwind CSS が値を remで生成してくれるというメリットを損なってしまいます。

そこで私は以下のようにします。

const rootFontSize = 10 // :root の font-size が 62.5% なら 10、100% なら 16

module.exports = {
  theme: {
    spacing: {
      0: '0',
      1: `${1 / rootFontSize}rem`,
      2: `${2 / rootFontSize}rem`,
      3: `${3 / rootFontSize}rem`,
      4: `${4 / rootFontSize}rem`,
      5: `${5 / rootFontSize}rem`,
      6: `${6 / rootFontSize}rem`,
      7: `${7 / rootFontSize}rem`,
      8: `${8 / rootFontSize}rem`,
      9: `${9 / rootFontSize}rem`,
      10: `${10 / rootFontSize}rem`,
    // 以下好きなだけ追加

これをもっと扱いやすくしてみましょう。

const rootFontSize = 10 // :root の font-size が 62.5% なら 10、100% なら 16
const maxSpacing = 100 // spacing の最大値

module.exports = {
  theme: {
    spacing: {
      ...Array.from({ length: maxSpacing + 1 }, (_, i) => i).reduce((result, currentIndex) => {
        const n = 1 // この値の倍数のみ生成
        if (currentIndex % n === 0) {
          result[currentIndex] = `${currentIndex / rootFontSize}rem`
        }
        return result
      }, {}),
    },
    // 以下略

こうすることで、rootFontSize の値を変更すると、
:root の font-size が 100% であっても 62.5% であっても
.mt-10 が margin-top: 0.625rem or 1rem(ともに10px相当)として生成することが可能となり、
さらに spacing の生成数を n の倍数に限定することも簡単です。

なお spacing で設定した値は margin padding だけでなく 以下のような頻出のプロパティにも使用可能です。
width max-width min-width height min-height max-height gap row-gap column-gap
(v3.4.3 時点)

参考:公式ドキュメント
https://tailwindcss.com/docs/customizing-spacing

これでだいぶ扱いやすくなったのではないでしょうか?
ここで扱った spacing の出力値の制限は、デザインガイドラインに沿った実装をする上で非常に重要です。

その他の設定

module.exports = {
  // 略
  prefix: 'tw-', // mt-10 ではなく tw-mt-10 と接頭辞をつけたいとき
  important: true, // !important つけたいときに。
  theme: {
  // 略
},

もし既存のプロジェクトに後から導入するのであれば、接頭辞をつけることで class 名の重複を避けることが可能です。

Tailwind CSS のみで構築するのであれば important は不要でしょうが、既存のCSSに追加として Tailwind CSS を導入する場合、詳細度負けしてしまうことがあります。
ユーティリティクラスですので確実に効かせるために、important を付与してもよいでしょう。

私は ユーティリティ以外の CSS をカスケードレイヤーで囲むのも一つの手だと思います。

Tailwind CSS のコーディング補助ツール

Tailwind CSS の class 名、「こんなにたくさん覚えられないよ」って思いますよね。

公式ドキュメントを見れば大丈夫です。
わからないプロパティがあったら、ここで探すとよいでしょう。

https://tailwindcss.com/

チートシートもありますが、最新版には対応しきれていないようです。

https://tailwindcomponents.com/cheatsheet/

VS Code であれば、公式から IntelliSense for VS Code という拡張機能も出ており、
導入すると入力補完が効きますので class 名は、うろ覚えでも大丈夫です。

スクリーンショット:VisualStudio Code のHTMLファイル編集画面。class属性にjustify-と入力したところでjustify-normal justify-start などの ユーティリティクラスの入力補完が効いていることが示されている

IntelliSense for VS Code
https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss

Tailwind CSS v4.0 について

この記事の執筆中(2024/3/7)に Tailwind CSS の 次のメジャーバージョンが、開発中であることが発表されました。

早速ですが現時点でリリースされているアルファ版(alpha.13 まで検証)を触ってみました。
触ってみてわかったことは以下の通りです。
※ 2024年4月時点の情報ということにご留意ください。

大きな変更点

  • ディレクティブの記述が変わる
  • 設定の記述を、tailwind.config.js ではなく、ソース側 CSS ファイルに記述していく方向性が示される(上であれだけ、カスタム方法を書いたというのに・・・・・・)

変更点1: ディレクティブの記述

@tailwind base;
@tailwind components;
@tailwind utilities;

このディレクティブ記述がつかえないです。(現時点では)

@tailwind base;
@tailwind components;

この2つの記述はそのまま出力されます。(現時点では)
なぜか@tailwind utilities;だけは効きます。

今後は

@import "tailwindcss";

もしくは

@import "tailwindcss/preflight" layer(base);
@import "tailwindcss/theme" layer(theme);
@import "tailwindcss/utilities" layer(utilities);

となるようです。

下の書き方のほうが、個人的に好みですね。不要な時に剝がしやすいので。
layer(~~) の記述を削除すれば、カスケードレイヤーに囲まれず出力されます。
他の CSS と共存させるときは、その点に注意が必要です。

変更点2:カスタム設定を CSSファイルに記述可能に

tailwind.config.js に記述していた設定値の変更も以下の様に、CSS ファイルに記述できるようになります。

@import "tailwindcss/preflight" layer(base);
@import "tailwindcss/theme" layer(theme);
@import "tailwindcss/utilities" layer(utilities);

@theme {
  --color-blue-700: blue;

  --spacing-10: 1rem;

  --font-size-base:

  --breakpoint-md: 768px;
}

以下のように記述することで、tailwind.config.js で theme 直下に書いたときと同様に、
元の値をクリアした上で、上書きします。

@theme {
  --color-*: initial;
  --color-blue-700: blue;

  --spacing-*: initial;
  --spacing-10: 1rem;

  --font-size-*: initial;
  --font-size-base:

  --breakpoint-*: initial;
  --breakpoint-md: 768px;
}

現時点では、tailwind.config.js に記述していたカスタム設定は、効かなくなっています。
今後、CSS ファイルのみで、カスタム設定ができるようにしたいという意図が伝わってきますね・・・

ただし、「今はまだできていないけど、tailwind.config.js との互換性を持たせる」といった記述や、「破壊的な変更」に対する否定的な記述、「互換性を重視している」といった記述があることから、リリース版では対応してくれるのではないでしょうか。
ディレクティブに関する記述も互換性を持たせてほしいですね。
あれも破壊的な変更と言えますので。

対応してくれますよね?(切実)

https://tailwindcss.com/blog/tailwindcss-v4-alpha

追加予定の機能

コンテナクエリに正式対応

これまで別途プラグインをインストールする必要があったコンテナクエリに正式対応するようです。
アルファ版で既に実装済みでした。
これまでコンテナクエリはプラグインを追加しても、

@container (min-width: xxx) {...}

このようにモバイルファーストの記述しかできなかったのですが、
v4.0 からは以下のように記述することで、モバイルファーストか、デスクトップファーストかを、
切り替えることが可能になります。

<div class="@container/containerName">
    <div class="@min-sm/containerName:block"></div>
    <div class="@max-sm/containerName:flex"></div>
</div>

コンテナクエリの完全対応は個人的に待ち望んでいた機能であり、このアップデートにおける最大の目玉だと思っています。

2023年12月のアップデートでも以下のような機能が追加されたばかりです。

  • 単位 dvh svh lvh
  • :has() 擬似クラス
  • text-wrap: balance text-wrap: pretty
  • subgrid

このようにアップデートの度に、使い勝手がよくなる進化を続けているため、
今後のアップデートも非常に楽しみな CSS フレームワークです。
(後方互換だけは頼みます・・・ホント・・・)

Tailwind CSS が解決してくれること

ここまで Tailwind CSS を推して推しまくってきましたが、
個人の好みとして、なんでもユーティリティクラスで解決させるというのは、あまり好きではありません。
※ デザインルールという制約を強固なものとする目的であれば別として

コンポーネントファーストの場合、デザイン段階で設計がしっかりと成されてさえいればユーティリティクラスを多用する必要はないですし、ユーティリティクラスを使用せず解決していけるに越したことはないです。

しかし、そうして解決していくしかないという「実情」もあります。

イレギュラーなデザインに、真正面から class 名を考えていくと途方もない時間がかかり、
結果として実装工数が膨れ上がります。
Tailwind CSS は、こうした現実的な課題に対して有効な解決策を提供してくれます。

Tailwind CSS に限らない話ですが CSS を設計するということで、もたらされる最大の利益は、
「先々の作業コストを削減すること」だと思います。

Tailwind CSS は、そのための効果的な選択肢の一つであり、適切に利用すれば、将来的なメンテナンスの容易さや開発の迅速化を実現し、より良い成果を生み出すことに貢献できるでしょう。

最後に

この記事では、意図的に触れませんでしたが、本来であれば React / Vue といった
コンポーネントベースのフレームワークでこそ Tailwind CSS は輝くでしょう。
(ただ、UIフレームワークを使用する場合は相性問題がある点に注意が必要ですし、個人的に React を扱うときは CSS Modules や styled-components を使うほうが好きだったりします。)

Vue.js Nuxt.js 案件のご相談は、ルート・シーまで。

< ノウハウのトップへ戻る