tailwind.config.js のよく使う設定

この記事は [ここのえ Advent Calendar 2023](https://qiita.com/advent-calendar/2023/99no_exit) Day 8の記事です。

# Intro

Tailwindを使い始めてだいたい1年ぐらい、4～5個ぐらいのプロジェクトを経て大分仲良くなりました。

プロジェクトに応じて `tailwind.config.js` は色々調整することになりますが、備忘録的によく使う設定についてまとめていこうと思います。

Tailwindのバージョンは、`v3.3.x` を対象としています。

# 主要な設定

まず最初に、`theme` 以外の主要な設定です。

## content

```js
content: [
  "./resources/**/*.blade.php",
  "./resources/**/*.ts",
  "./resources/**/*.vue"
],
```

HTMLやJSといった、Tailwindを記述する対象となるファイルを規定します。
上記の例は `Laravel` + `Typescript` + `Vue` の環境です。
導入直後にうまくTailwindが反映されていなかったら、まずここを疑いましょう。

## darkMode

```js
darkMode: "class",
```

darkModeの設定方法を変えるオプションです。

標準ではOSの設定に基づいてダークモードの設定を変える挙動になりますが、`class` を指定しておくことで、`<body class="dark">`のように`dark`クラスを与えてダークモードの切り替えが手動で出来るようになります。

OSの設定をダークにするとWindowsのエクスプローラまで真っ黒になってしまい、気に入らないからライトにしてるけど、Webサイトはダークモードで使いたい……という需要はそこそこあると思うので、この設定で簡単に対応できます（主に自分）。


## safelist
```js
safelist: [
  'text-3xl',
  {
    pattern: /grid-cols-([1-9]?[1-9])/
  }
],
```

Tailwindの挙動として、先に挙げた`content`に書かれたファイル内で記述されたCSSユーティリティのみをコンパイルし、不必要なものがバンドルされないようにする、という特徴があります。

もちろんこれは嬉しい機能なのですが、`React`や`Vue`を使って動的にクラスを当てたい場合、これが裏目に出て当てたクラスが反映されない問題が発生します。

ここで登場するのが `safelist` の設定で、ここに記述されたものは `content` 内のコードがあるなしに関わらず、出力されるCSSにパッケージされて同梱されるようになります。必要に応じて追加しましょう。

**当然ですが、何でもかんでもsafelistに突っ込むのは止めましょうね！**

:::note info
### Tips: 動的に当てるclassを作っておく技
とはいえ毎回 `tailwind.config.js` を触るのは面倒ですし、極力ファイル内にとどめて置きたいですよね。そんな時に使える裏ワザ(?)です。

`sass`と`vue`の組み合わせを示しますが、自分の環境に合わせて変えてください。

```sass
.button
  @apply text-left text-black bg-blue-300 rounded-lg

  &.active
    @apply text-white bg-blue-500

  &.inactive
    @apply text-white bg-gray-800
```

```vue
<script>
const isActive = computed(() => {
  return 何かの条件 ? 'active' : 'inactive'
})
</script>
...

<div :class="['button', isActive]">
```

クラスを予めCSS内に定義しておき、それを`vue`で動的に当てたり外したりすることで、デザインの変更を実現します。

この方法であればCSS内には書かれているので、いちいち`safelist`を使わなくても大丈夫です。

:::

# themeの設定

本題ともいえる、`theme`の設定です。
各種コンフィグに加えて、ユースケースについても紹介していきます。

## `extend`か否か？

themeの設定ですが、以下のように2つのタイプの設定ができます。

```js
theme: {
  // 既存設定を上書きする
  colors: {
    "primary": "#000000"
  }

  // 新たに追加する
  extend: {
    screens: {
      xs: "350px"
    }
  }
}
```

`theme`直下に設定を書いた場合、デフォルトの設定を上書きしてしまいます。
上記のようなコードを書くと、`text-white`や`bg-blue-500` のように、標準で定義されていたカラーは **上書きされて消え**、`primary`のみが色として指定できるようになります。

対して `extend` 内に書いた設定については、デフォルトの種類に加えて使えるようになります。

以下のように使い分けると良いと思います。

- デザイン規定に確実に従わせるため、使える配色を固定したい
  - `theme:` 直下に色を定義して、デフォルト色を消す
- screenのbreakpointとして、`xs`や`xxl`を追加したい
  - `extend` 以下に追加し、`sm`や`md`に加えて使えるようにする

## colors

```js
colors: {
  "primary": "#000000",
  "on-primary": "#ffffff",
  "primary-container": "#222222",
  "on-primary-container": "#cccccc",
}
```

文字通りカラーの指定です。
ここで指定することで、`text-primary`, `bg-primary`といった各種ユーティリティにおける色指定で選択できるようになります。

## screens

```js
screens: {
  xs: '350px'
},
```

`sm:`, `md:`, `lg:`といったbreakpointに、新たなサイズを定義できます。
自分の場合はよく`xs`を定義しています。

## outlineColor

```js
outlineColor: "#aaaaaa",
```

outlineの色のデフォルト値を設定できます。
後述の「変数を利用したカラー設定」と併用すると便利です。

## animation/keyframes

```js
animation: {
  "fadein": "fadeinkey 0.3s",
},
keyframes: {
  "fadeinkey": {
    "0%": {opacity: 0},
    "100%": {opacity: 1}
},
```

`keyframe`や`animation`を簡単に定義しておくことができます。
**GSAP** や **Anime.js** を使うまでもないアニメーションについては、これを使うと便利です。

コンフィグ内で無理に書きこむ関係で、Tailwindをサポートしてるエディタ・プラグインでもあまり補完が効かずちょっと書きづらいのが難点です。無理に使わなくても良いと思います。

## 変数を利用したカラーテーマの設定

Tailwindの `colors:` の設定ですが、こんな感じでCSS変数を読み込んで当てることもできます。

```js
colors: {
  "primary": "var(--theme-primary)",
  "on-primary": "var(--theme-on-primary)",
  "outline-color": "var(--theme-outline-color)"
}
```

Tailwindを読み込んでいるメインのcssにこんな感じで定義しておくと、当てるクラスによってテーマを変更することができ、簡単に複数テーマの実装を行うことができます。大変重宝します。

```sass
@tailwind base;
@tailwind components;
@tailwind utilities;

.theme-light
  --theme-primary: #00639b
  --theme-on-primary: #ffffff
```

以前に色々試してみたのですが、`"primary": "$theme-primary"`のようにsass変数を直で使うのは無理そうでした。
もしやり方があったら教えてください……

# まとめ

他にもオプションが多く用意されており、かゆいところに手が届くので、プロジェクト全体で共通の設定はコンフィグを活用すると幸せになれます( ◜◡◝ )

# 参考資料

https://tailwindcss.com/docs/theme

https://stackoverflow.com/questions/64872861/how-to-use-css-variables-with-tailwind-css