Tailwind CSS実践入門 ~まず作ってから、あとで共通化する

Tailwind CSS実践入門
第3章 Tailwind CSSの活用
─⁠─ユーティリティクラス⁠修飾子⁠カスタムスタイル

本章では、ユーティリティクラスの調べ方や、擬似クラス、擬似要素などの使用方法、カスタムスタイルを追加する方法に加えて、Tailwindと組み合わせて使うライブラリについても説明します。

ユーティリティクラスの調べ方

Tailwindでは、かなりの数のユーティリティクラスが提供されており、一般的に使用されるCSSプロパティのほとんどがカバーされています。ある程度マイナーなCSSプロパティも含まれていれば、ユーティリティクラスとして表現することが難しそうな機能についてもうまく実装されていたりもします。

その分、使用できるクラスやその使い方を把握するのが難しそうにも思えますが、最初からすべてのクラスを覚える必要はありません。というのも、CSSプロパティの名前さえ覚えていれば、あとはエディタの補完機能に頼るだけでなんとかなるからです。Tailwindのユーティリティクラスの多くは、それと対応するCSSプロパティにちなんだ名前になっています。クラス名として、プロパティ名の一部や、margin-topであればmtなどの頭字語を入力すれば、あとはエディタに表示される候補の中から選択できます。

もしそれで必要なクラスを見つけられなかったとしても、Tailwindの公式ドキュメントにある検索機能を使用すれば簡単に見つけられます図1⁠。Tailwindの公式ドキュメントでは優れた検索機能が提供されており、入力したキーワードをもとにしてドキュメント全体からの逐次検索をしたり、入力したキーワードに誤字が含まれていてもうまく解釈したりできます。

図1 Tailwind公式ドキュメントの検索機能
図1

紙幅の都合により、すべてのユーティリティクラスを掲載することができませんが、代わりに、有志によって作成されているチートシートをいくつか紹介します。まず、すべてのユーティリティクラスを一覧するには、Tailwind Componentsという非公式プロジェクトで作成されているチートシートが便利です図2⁠。

図2 Tailwind Componentsによるチートシート
図2

また、ユーティリティクラスだけではなく、スペーシングやカラーパレット、ブレイクポイントや擬似クラスの修飾子なども併せて確認したい場合には、UmeshKadam氏によるチートシートが役に立ちます。

すべてのユーティリティクラスを覚えるのは無理があります。そのため、最初のうちはこうしたチートシートも活用しながら、Tailwindを実際に使用する中で慣れていくのがよいでしょう。

擬似クラス⁠擬似要素⁠メディアクエリなど

Tailwindでは、ユーティリティクラスに特定の修飾子を付与することで、条件に応じたスタイルの適用ができます。たとえば、ホバーされているときにbg-sky-700クラスを適用するには、hover:bg-sky-700クラスを使用します。

<button class="bg-sky-500 hover:bg-sky-700 ...">変更を保存</button>

ホバーのほかにも、Tailwindではさまざまな修飾子が使用できます。擬似クラスに擬似要素、メディアクエリのブレイクポイント、ダークモード、属性セレクタなど、一般的に必要とされる機能は一通り網羅されています。

そして、これらの修飾子を複数組み合わせることもできます。たとえば、ダークモード環境において、ブレイクポイントのmdを使いながら、ホバーされているときに背景色を変更したい場合は、次のように記述します。

<button class="dark:md:hover:bg-fuchsia-600 ...">変更を保存</button>

修飾子は任意の順番で記述できます。

また、親要素の状態に応じたスタイリングや、隣接する要素の状態に応じたスタイリングをすることもできます。さらに、Tailwindには含まれていない修飾子を独自に追加することもできます。

本節では、Tailwindで使用できる修飾子のうち、主要なものだけに絞って紹介します。すべての機能を確認したい場合は、公式ドキュメントを参照してください。

ホバー⁠フォーカス⁠アクティブ

hoverfocusactive修飾子を使用することで、ホバー、フォーカス、アクティブの状態に応じたスタイリングができます。

<button class="bg-violet-500 hover:bg-violet-600 active:bg-violet-700 focus:outline-none focus:ring focus:ring-violet-300 ...">変更を保存</button>

最初⁠最後⁠奇数⁠偶数

firstlast修飾子を使用することで、対象の要素が、最初の子要素か最後の子要素かに応じたスタイリングができます。次の例では、最初の子にある上部のパディングと、最後の子にある下部のパディングを取り除くようにしています。

<ul class="p-6 divide-y divide-slate-200">
  {#each people as person}
    <li class="flex py-4 first:pt-0 last:pb-0">
      <!-- ... -->
    </li>
  {/each}
</ul>

oddeven修飾子を使用することで、要素が要素が奇数か偶数番目かに応じたスタイリングができます。次の例では、奇数番目の行では白背景を、偶数番目の行ではslate-50の背景を適用しています。

<table>
  <tbody>
    {#each people as person}
      <tr class="odd:bg-white even:bg-slate-50">
        <!-- ... -->
      </tr>
    {/each}
  </tbody>
</table>

祖先要素の状態に応じたスタイリング

対象の要素自身ではなく、その祖先要素の状態に応じてスタイリングすることもできます。祖先要素にgroupクラスを追加したうえで、スタイリングする対象の要素にはgroup-hoverのような修飾子を使用します。これは、group-という接頭辞にほかの修飾子を組み合わせたものです。

<a href="#" class="group block bg-white hover:bg-sky-500">
	<svg class="stroke-sky-500 group-hover:stroke-white">
		<!-- ... -->
	</svg>
</a>

::before::after

beforeafter修飾子を使用することで、::before::after擬似要素のスタイリングができます。

<span
  class="block text-sm font-medium text-slate-700 after:content-['*'] after:ml-0.5 after:text-red-500"
>
  メールアドレス
</span>
<input type="email" name="email" class="..." />

これらの修飾子を使用すると、自動的にcontent:''が適用されます。したがって、この値を変更する必要がなければ、そのためのクラスは不要です。

ただし基本的には、擬似要素の代わりにHTML要素を使用するほうが簡単です。たとえば<span>要素を使用したほうが、コードは簡潔かつ読みやすくなります。

<span class="block text-sm font-medium text-slate-700">
  メールアドレス
<span class="ml-0.5 text-red-500">*</span>
</span>
<input type="email" name="email" class="..." />

メディアクエリのブレイクポイント

mdlgなどの修飾子を使用することで、特定のブレイクポイントに向けたスタイリングができます。たとえば次のようにすると、狭い幅では3カラム、中程度の幅では4カラム、大きな幅では6カラムのグリッドになります。

<div class="grid grid-cols-3 md:grid-cols-4 lg:grid-cols-6">
  <!-- ... -->
</div>

ブレイクポイントの種類や値については、Tailwindの設定から変更できます。

WAI-ARIAの状態

aria-*修飾子を使用することで、WAI-ARIAWeb Accessibility Initiative - Accessible Rich Internet Applicationsの状態に基づいたスタイリングができます。たとえば、aria-checked属性の値がtrueの場合にbg-sky-700を適用するには、aria-checked:bg-sky-700クラスを使用します。

<div
  aria-checked="true"
  class="bg-gray-600 aria-checked:bg-sky-700"
>
  <!-- ... -->
</div>

真偽値を取るWAI-ARIAの属性のうち、一般的なものが修飾子として使用できます表1⁠。

表1 WAI-ARIAの状態にもとづいた修飾子
修飾子 セレクタ
aria-checked &[aria-checked="true"]
aria-disabled &[aria-disabled="true"]
aria-expanded &[aria-expanded="true"]
aria-hidden &[aria-hidden="true"]
aria-pressed &[aria-pressed="true"]
aria-readonly &[aria-readonly="true"]
aria-required &[aria-required="true"]
aria-selected &[aria-selected="true"]

カスタムスタイルを追加するためのパターン

Tailwindに最初から用意されているスタイルのほかに、独自のスタイルを追加して使用することもできます。そのためにはいくつかの方法があり、必要に応じて使い分けることが重要です。

本節では、それらの方法のうち主要なものに絞って紹介します。そのすべてを確認したい場合は、公式ドキュメントを参照してください。

テーマのカスタマイズ

Tailwindで使用するカラーパレットや余白、文字サイズなどやブレイクポイントを変更したければ、tailwind.config.jsthemeを変更します。

tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ['./src/**/*.{html,js}'],
  theme: {
    colors: {
      'blue': '#1fb6ff',
      'purple': '#7e5bef',
      'pink': '#ff49db',
      'orange': '#ff7849',
      'green': '#13ce66',
      'yellow': '#ffc82c',
      'gray-dark': '#273444',
      'gray': '#8492a6',
      'gray-light': '#d3dce6',
    },
    fontFamily: {
      sans: ['Graphik', 'sans-serif'],
      serif: ['Merriweather', 'serif'],
    },
    extend: {
      spacing: {
        '128': '32rem',
        '144': '36rem',
      },
      borderRadius: {
        '4xl': '2rem',
      }
    }
  },
}

詳しくは、第2章のTailwind CSSの設定の節を参照してください。

自由な値の使用

通常Tailwindでは、テーマとして設定した値に基づいてスタイリングをしますが、必要に応じて、その設定から逸脱した値を使うこともできるようになっています。

たとえば、topプロパティの値として117pxを使用したい場合には、その値を[]で囲うことで、対応するクラスが動的に生成されます。

<div class="top-[117px]">
  <!-- ... -->
</div>

このクラスでは、hoverlgなどの修飾子を使用することもできます。

<div class="top-[117px] lg:top-[344px]">
  <!-- ... -->
</div>

さらに、[]の中ではtheme関数を使用することもできます。これを使うと、テーマの設定を参照できます。

<div class="grid grid-cols-[fit-content(theme(spacing.32))]">
  <!-- ... -->
</div>

Tailwindのユーティリティクラスに含まれていないCSSプロパティを使用したければ、CSSの宣言全体を[]で囲います。

<div class="[mask-type:luminance]">
  <!-- ... -->
</div>

このクラスでは、hoverlgなどの修飾子を使用することもできます。たとえば、条件に応じてカスタムプロパティの値を変更したい場合などに便利です。

<div class="[--scroll-offset:56px] lg:[--scroll-offset:44px]">
  <!-- ... -->
</div>

CSSファイル内での@layerの使用

場合によっては、Tailwindを使用しながらも独自のCSSを記述する必要があるかもしれません。その場合は、普通と変わりなくCSSファイルに追加できます。

tailwind.config.js
@tailwind base;
@tailwind components;
@tailwind utilities;

.my-custom-style {
  /* ... */
}

このような独自の CSS を追加する場合には、Tailwindの@layerディレクティブを使用することで、いくつかの機能が有効になります。@layerディレクティブでは、base/components/utilitiesのうち適切なレイヤを指定します。

tailwind.config.js
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer components {
  .my-custom-style {
    /* ... */
  }
}

これによって、CSSの宣言の順序が制御できるようになるほか、Tailwindのhovermdなどの修飾子が利用可能になります。また、ソースコード上でそのクラス名が使用されているかが検査されて、使用されていない場合にはCSSが出力されないようにもなります。

プラグインの作成

独自のスタイルを追加するために、Tailwindのプラグインシステムを使用することもできます。

tailwind.config.js
const plugin = require('tailwindcss/plugin')

module.exports = {
  // ...
  plugins: [
    plugin(function ({
      addBase,
      addComponents,
      addUtilities,
      theme,
    }) {
      addBase({
        h1: {
          fontSize: theme('fontSize.2xl'),
        },
        h2: {
          fontSize: theme('fontSize.xl'),
        },
      })
      addComponents({
        '.card': {
          backgroundColor: theme('colors.white'),
          borderRadius: theme('borderRadius.lg'),
          padding: theme('spacing.6'),
          boxShadow: theme('boxShadow.xl'),
        },
      })
      addUtilities({
        '.content-auto': {
          contentVisibility: 'auto',
        },
      })
    }),
  ],
}

プラグインでしかできないことはいくつかあります。一つは、ユーティリティクラスを動的に生成することです。Tailwindにある多くのユーティリティクラスは、値の指定に応じて動的に生成されるしくみになっています。このしくみは、次のように実装できます。

tailwind.config.js
const plugin = require('tailwindcss/plugin')
module.exports = {
  theme: {
    tabSize: {
      1: '1',
      2: '2',
      4: '4',
      8: '8',
    },
  },
  plugins: [
    plugin(function ({ matchUtilities, theme }) {
      matchUtilities(
        {
          tab: (value) => ({
            tabSize: value,
          }),
        },
        { values: theme('tabSize') }
      )
    }),
  ],
}

こうして実装したユーティリティクラスには、次のように[]を使って自由な値を指定することもできます。

<div class="tab-[13]">
  <!-- ... -->
</div>

プラグインの作成方法については、詳しくは公式ドキュメントを参照してください。

また、プラグインとして実装されたクラスは、CSSファイルとして記述される場合と違って、エディタの入力候補として表示されるようになります。

Tailwind UI

Tailwindでは、既成のUIコンポーネントは提供されていません。代わりにTailwind UIという公式プロジェクトで、UIコンポーネント集や用途別のテンプレートが提供されています。

コンポーネントは、マーケティング向け、アプリケーションUI向け、EC向けに分類されて、500以上の数のものが提供されています図3⁠。

図3 Tailwind UIで提供されているコンポーネント
図3

ただし、いずれも利用は有料です。個人用とチーム用のプランが用意されているため、必要なものを選んで購入するとよいでしょう。

Headless UI

Tailwindでは、UIコンポーネントを動作させるためのJavaScriptなどは提供されていません。そのため、Tailwindとは別に用意する必要があります。しかし標準的なUIコンポーネントについては、同じような振る舞いになることがほとんどであるため、汎用的なライブラリを使って解決したいところです。

Bootstrapのように既成のUIコンポーネントを提供するフレームワークでは、スタイルと振る舞いがセットになって提供されることが一般的です。一方でTailwindの場合、独自のスタイルを作成できることに主眼が置かれているため、既成のスタイルは不要です。そこでTailwindでは、スタイルは自由に作成できるように、振る舞いだけに焦点を当てたライブラリのHeadless UIを提供しています。

Headless UIは、ReactとVue.jsに向けていくつかの振る舞いのパターンを提供していますが、数はあまり多くないことが欠点です。そのため、Tailwindとは別のチームによって開発されているRadix UIを代わりに採用してもよいでしょう。

また、ReactやVue.jsなどのライブラリを採用せずに、サーバサイドから出力されたHTMLをもとにしてJavaScriptを実装する環境に向けてはAlpine.jsの採用が提案されています。さらに、同ライブラリとともに開発されているAlpine UI Componentsでは、Headless UIと同様の実装が提供されています。

まとめ

本章では、Tailwindを使ってスタイリングしていくための方法について解説しました。次章では発展編として、デザインプロセスにおけるユーティリティファーストの意味、CSS設計のあるべき考え方、CSSの特性を活かしてデザインするためのアプローチについて紹介します。

おすすめ記事

記事・ニュース一覧