Tailwind CSSで、よく使いそうなのにやり方がわからなかったこと

個人サイトや検証のみで使っていた「Tailwind CSS」を案件で使うようになり、これまで必要なかったマークアップやコンフィグの書き方が必要になってきました。
案件で使うなら、これは知っていないとまずい…と思ったものをまとめておきます。

## コンフィグ関係

### 色の追加

Tailwindには多彩なカラーテーブルが用意されています。ですが、サイトのブランドカラーが赤いからといって、コンフィグで`red`を書き換えるのは、あまりよい手法ではなさそうです。ブランドカラーが未来永劫「赤」であるとは限らないからです。

#### 多色

以下のようにextendプロパティを指定することで、`.brand-***`というクラス群を追加できます。

[カラーチャート/カラーグラデーション \- TAG index](https://www.tagindex.com/color/color_gradation.html)

```:tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        'brand': {
          '100': '#f8fcfc',
          '200': '#f1f8f8',
          '300': '#e2f1f1',
          '400': '#c7e2e2',
          '500': '#8dc7c7',
          '600': '#55aaaa',
          '700': '#478d8d',
          '800': '#2b5555',
          '900': '#1d3838'
        }
      }
    }
  }
}
```

#### 単色

追加する色がひとつで良い場合は、Tailwindのルールからは外れますが、以下のように書くと`.brand`が使用できます。

```:tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        'brand': '#55aaaa'
        }
      }
    }
  }
}
```

### フォントの追加

最近の日本のウェブサイトでは、多彩なウェブフォントを使います。装飾フォントを追加したい場合は、色のときと同様にクラスを追加するのが良さそうです。以下のように書くと`.font-ja1`が使用できます。


```js:tailwind.config.js
module.exports = {
  theme: {
    extend: {
      fontFamily: {
        ja1: '"Nico Moji", sans-serif'
      }
    }
  }
}
```

## HTMLに関係なく、絶対入っててほしいクラス

Tailwind CSSはバージョン3以降、CSSをビルドしたときに公開ディレクトリのHTMLを解析し、存在しているクラスのみを書き出すようになりました。この場合、例えばJavaScriptやPHPなどで、動的に書き換えられたときのクラスを書き出してくれません。HTMLに存在していないからです。

また、すぐにCSSをビルドできない状況で、余白や文字サイズをちまちま調整しなければならなそうなときも、この仕様はけっこう困ります。

// そんなグダグダなことはあってはならない？CMSで管理しているサイトのイベントページでは日常茶飯事です

safelistプロパティで、常に書き出してほしいクラスを指定することができます。ここでは公開後の運用で非常によく使う`.m-数字`と`.p-数字`を指定しています。

```js:tailwind.config.js
module.exports = {
  safelist: [
    {
      pattern: /^(m|p)-[0-9][0-9]$/
    }
  ]
}
```

## マークアップ関係

### 親要素にカーソルを置いたら、子要素のスタイルが変わる

「親要素のブロック化したリンクにカーソルを置いたら、子要素の見出しにアンダーラインが入る」
という演出は、アクセシビリティに配慮したいけど、文字を下線だらけにしたくない場合によくやります。親要素に`.group`クラスを付与し、アンダーラインを引きたい要素には`.group-状態:変更したいクラス`を付与します。

```html
<a href="#" class="group block p-4 hover:bg-gray-200">
    <h3 class="group-hover:underline font-bold mb-2">Lorem ipsum dolor sit amet</h3>
    consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</a>
```

### 要素が変化したら、兄弟要素のスタイルが変わる

チェックボックスだけでトグルメニューを作るときにやります。チェックボックスを展開したい要素の前に置き、`.peer/一意の名前`クラスを付与し、アンダーラインを引きたい要素には`.peer-状態/一意の名前:変更したいクラス`を付与します。

なお、`.peer`と`.peer-状態`は順番を逆にすることはできません。

```html
<input type="checkbox" aria-label="Menu Open" name="menu" class="peer/menu" />
<div class="overflow-hidden w-96 h-0 p-0 peer-checked/menu:h-auto peer-checked/menu:p-4">
    <h3 class="font-bold mb-2">Lorem ipsum dolor sit amet</h3>
    consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</div>
```

## 全クラスを使う

検証目的などで、ファイルサイズはいいから今のところは全クラスを自由に使いたい、という場合もあります。バージョン3時点では、下記リンク先のコンフィグを書くとすべて使えるようです。`tailwind.config_full.js`とかで保存しておくといいかもしれません。

[tailwindcss/stubs/config.full.js](https://github.com/tailwindlabs/tailwindcss/blob/master/stubs/config.full.js)

## やり過ぎ注意

一般的なコーディング案件でひんぱんに使いそうなのは、こんなところかなと思いました。
当然ながら、やり過ぎないようにしなくてはなりません。特にsafelistは、慎重に使わなければカオス化します。範囲を広げすぎるとCSSファイルが1MBとかになります。

デザイナー側にもガイドラインを伝えるなどして、スムーズなコーディングができるようにしたいものです。

## 参考

- [Content Configuration \- Tailwind CSS](https://tailwindcss.com/docs/theme)
- [Handling Hover, Focus, and Other States \- Tailwind CSS](https://tailwindcss.com/docs/hover-focus-and-other-states)