Tailwind CSSを半年使い込んで分かった便利な点 + 最新動向

## 概要

- Tailwind CSSを半年使い込んで分かった便利な点/注意点を説明する
- 最新v3.0のアップデート内容を紹介する

## はじめに

本記事では非常に便利なCSSフレームワークであるTailwind CSSについて説明します。

https://tailwindcss.com/

筆者はフロントエンドエンジニアとして仕事/趣味でこの半年いくつかのサービスやツールを実装しましたが、そのいずれでもTailwind CSSを利用しました。その中では素のCSSを書くことはほとんどありませんでした。例えば最近リリースされたDockpit liteというツールでもTailwind CSSをフル活用しています。

https://chrome.google.com/webstore/detail/dockpit-lite/mjbgnnaedaplnoahfejcifokefbhmalg

以下ではこうした経験の中で見えてきたTailwind CSSの特徴、便利なポイント、注意点をご紹介していきます。

また最後に最新のv3.0のアップデート内容を紹介します。

## Tailwind CSSとは

### Tailwind CSSの概要

Tailwind CSSは「ユーティリティファースト」なCSSフレームワークです。HTML要素のクラス名に`flex pt-4 text-center`といったユーティリティクラスを指定をすると対応するスタイルが当たります。ざっくりいえばCSSのシンタックスシュガー(or マクロ)です。

> A utility-first CSS framework packed with classes like flex, pt-4, text-center and rotate-90 that can be composed to build any design, directly in your markup. https://tailwindcss.com/

例えば以下のようにクラス名を記述していくと、文字サイズやフォントウェイト、背景色のグラデーションなどを実装できます。

![tailwindcssisawesome.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458395/97ea6abd-91d3-dfda-d2a0-6c60f3e779dc.png)

```tsx
<div 
    className={`
        my-4 text-center
        font-bold text-5xl tracking-tight
        bg-gradient-to-r from-green-500 via-blue-500 to-pink-500
        bg-clip-text text-transparent 
    `}
>
    Tailwind CSS is Awesome
</div>
```

### Tailwind CSSの便利な点

さて、このTailwind CSSによって何が便利になるのでしょうか？

まずユーティリティクラスによってCSSの実装が簡単になる点が便利です。例えばよく使われる以下のようなCSSも`truncate`というより簡単なクラス名で表現することができます。

```css
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
```

またマークアップ(+ロジック)とスタイルを別々のファイルに書く必要がない点も便利です。例えばReactならJSXの中にクラス名によってスタイルを記述することができます。

もちろんJSXには`style`プロパティが存在してスタイルを記述することができますが、擬似要素やメディアクエリを利用できません。一方でTailwind CSSではクラス名に接頭辞をつけるだけで擬似要素が記述できます。同様に接頭辞によってウィンドウ幅に応じたスタイルを記述することができるため、レスポンシブデザインが簡単に実装できます。

例えば以下のようにクラス名を記述するとhoverした時に色の変わるボタンを実装できます。ついでにアニメーションも追加できます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458395/fb056afe-9515-8c35-87b3-e805f5535c3f.gif" width="50%">

```tsx
<button 
    className={`
        bg-blue-500 hover:bg-yellow-500 
        p-3 rounded-full font-bold transition duration-300
        text-white
    `}
>
Hover Button
</button>
```

またTailwind CSSは`w-1`=`width:0.25rem`=`width:4px`、`w-2`=`width:0.5rem`=`width:8px`...というように単位が統一されています。それゆえにスタイル全体に単位の規約を自然と適用することができます。特に複数人で実装する際には効果を発揮するでしょう。

一方でこの単位系だけでは表現しきれないスタイルも存在します。そうしたスタイルを実装したい場合は`w-[10px]`といった形で任意の値を用いることもできます。

https://tailwindcss.com/docs/adding-custom-styles#using-arbitrary-values

もちろんこの任意の値を使った場合はスタイル全体での単位の統一が崩れてしまうので注意が必要です。

またTailwind CSSはカラーパレットを持っており、それぞれの色を`blue-500`といった形で記述できます。明度に単位が設定されているのも便利です。単位系と同様にこのカラーパレットを活用することでスタイル全体での色の規約の導入ができます。

![スクリーンショット 2022-02-22 19.48.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458395/b10131ca-e0a7-c094-c15d-4154b3150d32.png)

https://tailwindcss.com/docs/customizing-colors

CSSとユーティリティクラス名の対応をいちいち調べるのが面倒という場合は、VSCodeの拡張機能が便利です。

https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss

HTMLやJSXでクラス名を記述する際に補完してくれるのに加えて、そのクラスに対応するCSSのツールチップを表示してくれます。

### 便利なユーティリティクラス

ここからは自分がTailwind CSSを利用してきて便利だったユーティリティクラスの一部をご紹介します。

#### グリッドデザイン

Tailwind CSSではグリッドデザインを簡単に実装することができます。コンテナとなる要素に`grid`というクラス名を指定し、横に何分割するかを`grid-cols-{amount}`で記述するだけです。またグリッド間の距離も`gap-{amount}`で定義することができます。

![スクリーンショット 2022-02-22 19.07.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458395/7f85926f-4618-789c-5eb2-11f92ce26e7f.png)

```tsx
<div className="grid grid-cols-3 gap-4 text-white font-bold">
  <div className="bg-blue-500 h-8 p-2">1</div>
// ...
  <div className="bg-blue-500 h-8 p-2">9</div>
</div>
```

https://tailwindcss.com/docs/display#grid

https://tailwindcss.com/docs/grid-template-columns

#### グラデーション

Tailwind CSSではグラデーションを簡単に記述できます。`bg-gradient-to-{direction}`でグラデーションする方向を定義し、`from-{color} to-{color}`でどの色からどの色へとグラデーションするのかを記述します。これらの色も先述のカラーパレットから選択するので、グラデーション内での明度の統一も簡単です。

https://tailwindcss.com/docs/gradient-color-stops

またグラデーションの中間色を定義したい場合は`via-{color}`クラス名を付与することができます。

#### アニメーション

`hover`など擬似クラスを定義した上で`transition`クラスを付与するとアニメーションを実装できます。

https://tailwindcss.com/docs/transition-property

追加して`duration-{amount}`でアニメーションの長さを指定できたり、`ease-in-out`などの変化を定義するクラスも用意されています。

https://tailwindcss.com/docs/transition-duration

https://tailwindcss.com/docs/transition-timing-function


#### 擬似クラス

先述の通り、`hover`や`focus`などの擬似クラスを`hover:bg-sky-700`といった接頭辞とクラス名の組み合わせで表現することができます。

https://tailwindcss.com/docs/hover-focus-and-other-states

さらに、特定の要素の親要素の状態に応じたスタイルを記述することもできます。親要素に`group`クラスを付与しておき、対象の要素に`group-hover:`といった接頭辞をつけたクラスを記述します。以下の例のように、親要素の任意の場所にカーソルが当たった場合に子要素の文字色を変えたい場合などに便利です。

![_2022-02-22 18.58.57.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458395/a05a6812-41e1-3530-551d-c13711bbecdc.gif)

```tsx
<div 
    className={`
        group 
        bg-blue-200 hover:bg-gray-600 
        w-auto m-6 text-center p-4 rounded 
        transition duration-300
    `}
>
    <div 
        className={`
        text-black group-hover:text-white 
        font-bold
        `}
    >
    group sample
    </div>
</div>
```

https://tailwindcss.com/docs/hover-focus-and-other-states#styling-based-on-parent-state

#### 透過

例えば背景色などを50%透過したい場合、`bg-{color}-{amount}/50`というように記述することができます。

![スクリーンショット 2022-02-22 19.19.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458395/0c967b89-1328-96f5-8024-6082f1ea56ad.png)

```tsx
<div className="bg-green-500 w-90 h-32 flex rounded">
    <div className="p-4 font-bold text-white text-2xl">Background</div>
    <div className="bg-blue-400/50 w-80 h-24 m-auto rounded absolute"/>
</div>
```

https://tailwindcss.com/docs/background-color#changing-the-opacity

もちろん透明度を別のクラス名で定義することもできますが、一つのクラス名で背景色と透明度を同時に定義できるので非常に便利です。

https://tailwindcss.com/docs/opacity

#### レスポンシブデザイン

各クラスに`md:`といった接頭辞をつけることでレスポンシブデザインを実装できます。以下のように各接頭辞がブレークポイントに対応しており、画面の幅がその条件を満たす場合に接頭辞をつけたクラスのスタイルが適用されます。毎回メディアクエリを記述することを考えると大幅に記述を簡略化できます。

|  接頭辞  |  幅  |  CSS  |
| ---- | ---- | ---- |
|  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) { ... }  |

https://tailwindcss.com/docs/responsive-design

#### 影

CSSで`box-shadow`を記述するのは地味に面倒ですが、Tailwind CSSでは非常に簡単に記述できます。`shadow-{amount}`クラスを付与するだけです。マウスホバー時に影をつけて浮き上がらせる表現も擬似クラスとの組み合わせで簡単に実装できます。

![スクリーンショット 2022-02-22 19.22.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458395/2f43f496-2c19-86c0-804f-83d2143da2c9.png)

```tsx
<div className="shadow-lg w-90 h-32 p-4 font-bold">Shadow</div>
```

https://tailwindcss.com/docs/box-shadow

## Tailwind CSSの注意点

### 導入時

ヘルプページに様々なフレームワークやボイラプレートへの導入手順が書かれているので簡単に使い始めることができます。

https://tailwindcss.com/docs/installation

```bash
npm install -D tailwindcss
npx tailwindcss init
```

ただし、tailwind.config.jsの`content`(v2以前なら`purge`)の項目に注意が必要です。この項目を正しく設定しないとクラス名を書いてもスタイルが当たらないという現象が発生する可能性があります。何度か使っていてもこの設定を忘れたり、間違ったりすることがありました。

```js
module.exports = {
  content: ["./src/**/*.{js,ts,jsx,tsx}"],
  theme: {
    extend: {},
  },
  plugins: [],
}
```

Tailwind CSSは全てのクラス名に対応するスタイルが含まれた巨大なCSSから、この項目で指定されたファイル群に書かれたクラス名に対応するものだけを抽出します。それゆえにここの設定が間違っていると記述されたクラス名に対応するスタイルが抽出されず、結果としてスタイルが当たらないという自体になり得ます。

あとは全体に当てているスタイルシート(Next.jsならglobals.css)に以下の記述が必要なのを忘れがちなので注意が必要かもしれません。

```css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

### 再利用性

ユーティリティクラスで記述したスタイルは便利な一方で再利用しづらいという問題があります。複数のスタイルを別の要素にも当てる際にはそれらに対応するクラス名をもう一度全て書く必要があるからです。

この点については以下の記事のような考え方が参考になります。

https://qiita.com/Takazudo/items/5180f5eb6d798a52074f

現代のフロントエンド開発は多くの場合Reactなどコンポーネントベースのフレームワークを活用します。同じスタイルを利用する=同じコンポーネントであると捉えて、再利用可能なコンポーネント化はReactなどに任せるわけです。

ただしこの考え方に従って再利用可能なコンポーネントを作っていくにはある程度スタイルの再利用性を考慮に入れながら実装を進めていく必要があります。この辺りは慣れが必要でしょう。

### 単位設定時の変数利用

`w-[10px]`のように任意の単位のスタイルを適用する際に、この`10px`といった値をJavaScript変数にすると動作しません。

```jsx
const widthVariable = '10px';
<div className={`w-[${widthVariable}]`}></div>
```

Tailwind CSS先述の通りビルド時にクラス名を読み取って対応するCSSファイルを作成するので、ビルド時に値が定まっていないとスタイルを当てられないためと考えられます。こうした場合は素直に`style`プロパティでスタイルを当てると良いでしょう。

## 最新v3.0のアップデート内容

Tailwind CSS v3.0が2021.12.10にリリースされました。メジャーバージョンアップということで様々な機能が追加されています。

https://tailwindcss.com/blog/tailwindcss-v3

特に大きいのが、Just-in-Timeモードのデフォルトでの有効化です。これによりビルド時間が大幅に短縮されました。

また`w-[10px]`といった任意の値を用いたスタイルはJust-in-Timeモードでのみ利用可能でしたが、それもビルドインの機能として利用できるようになりました。

Just-in-Timeモードを利用しない場合は開発時はCSSのパージ(ソースコードに書かれたクラス名に対応するスタイルのみを集めたCSSを生成する)が行われていませんでした。本番ビルドの際にのみそのパージが行われるという仕組みです。Just-in-Timeモードでは開発中も本番ビルド時と同じようにパージが行われます。これにより、いざ本番ビルドをしてみるとパージの設定が間違っていてスタイルが当たらないといった事故がなくなりました。これもありがたいです。

またv3.0から利用できる色が増えています。cyanやskyなどがカラーパレットに追加されており、ユーティリティクラスでこれらの色を使うことができます。

その他にも`print`接頭辞の追加などのアップデートがなされています。

以上のようにかなり革新的なアップデートです。移行手順ページもあるので自分も複数のプロジェクトでアップデートを行いました。

https://tailwindcss.com/docs/upgrade-guide

アップデートする上での注意点として、tailwind.config.jsの設定項目で`purge`が`content`に変更されています。先述の通りこの項目を正しく設定しないとスタイルが当たらないので、変更を忘れないようにしましょう。

## おわりに

本記事ではTailwind CSSの便利な点や注意点を紹介しました。もちろんCSSを使ったスタイリングについての前提知識は必要なものの、Tailwind CSSを習得/利用すると非常に便利にスタイルを実装することができるようになります。ぜひ活用してみてください。