Web制作経験者が「TailwindCSSだけじゃ、たいしたことできないんでしょ？」って思ってたら、TailwindCSSでいいじゃんとなった Ver.4

# TailwindCSSって使えなさそうだよね
みんな大好きTailwindCSS。

TailwindCSSはクラス名をつけて、CSSにプロパティを当てるのではなく、HTMLにクラス名を直接記述してスタイリングします。
```html:Tailwindの書き方例
<div class="flex justify-center items-center">
```

BEMとかの命名規則的なものでクラス名をSCSSファイルに書いていくには、クラス名を考えるのが結構しんどい。
コーディング進んでいくと、あれ、クラス名のアイデアがなくなってくるのはみなさん経験したことがあるはずです。

クラス名を考えなくていいのはいいんだけど、初見誰もが思うと思いますが、class=""の中がごちゃごちゃして汚いというか。。。

Reactで使うCSSはどうする？とかの記事や動画を見ていると、「TailwindCSSを使ってます。」ってよく見かけますが、コンポーネントを組みわあせるReactとかで使うなら一番良さそうだな。。。とは思いました。


https://tailwindcss.com/


<br>

![business_sabori_pc_solitaire.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111652/a36da5b4-faea-4fc7-b501-ebd20f2c6f56.png)


TailwindCSSの説明を見ていて思ってたのが、
`flex`とか`grid`はできそうだけど。。。
**「`p-4`とかってw。いや、こんなんデザイナーさんのデザイン再現できないでしょ？」**

Web制作をやったことがあったので、CSSが書けないエンジニアがそれっぽく楽に書くためのCSSフレームワークと考えていました。

```html:TailwindCSSの例
<div class="bg-blue-500 p-4 rounded">
  <p class="text-blue-100 mb-4">これはTailwindCSSのサンプルコード</p>
</div>
```

## この場合どうするの？
TailwindCSSはユーティリティファーストのCSSフレームワークと言われていて、SASSのようにCSSファイルにプロパティを書いていくのではなく、
`p-4`や`flex`などのユーティリティクラスをHTMLのclass属性に書いてスタイリングします。

```diff_html:書き方の比較
例：
- 従来: `.card { padding: 1rem; display: flex; }`
+ Tailwind: `<div class="p-4 flex">`
```

記事や動画ではTailwindCSSがどんなものかという解説は当然されているんですが、コーダー（ここでは、HTMLやCSSをメインで書くエンジニアを指します。）やデザイナーさんではないので具体的なコーディングについては、ほぼ説明されていません。

なので、TailwindCSSに対して、こんな疑問が生まれました。

<br>

![figure_question.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111652/a351d326-e94b-40f9-988c-32968290b2b0.png)


- 背景色が`bg-blue-500`、marginが`mb-6`とかそんなざっくりとした感じじゃなくて細かく設定するには？
- レスポンシブ対応とかどうするの？
- ホバーの時はどうする？
- ボックスシャドウとかの表現は？
- グラデーションはどうする？
- beforeとか擬似要素は使えないの？

こんなことはTailwindCSSだけでは、できないと思っていました。。。
でも、意外とすごいんです。TailwindCSS。
実はこれら、全てできます！

:::note info
Tailwind Playを使えば気軽にTailwindCSSを体感できます！
:::

https://play.tailwindcss.com/

### 余白と背景色の細かい設定をしたい

TailwindCSSで余白を指定する場合、`p-4`などの決まった値しかできないのかと思っていました。

`padding: 20px;`としたい場合は
```html:paddingの数値指定
<div class="p-[20px]">
    Padding
</div>
```
と指定することでpaddingを好きな余白にすることができます。

背景色を`bg-red-500`など決まったものではなく、`#ff1a00`などの色指定をしたい場合は
```html:background-colorの色指定
<div class="bg-[#ff1a00]">
    Background-Color
</div>
```
とpaddingと同じように、指定することでbackground-colorを好きな色に指定することができます。

### レスポンシブ対応はどうするの？
![smartphone_boy_stand.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111652/9dc2ea6b-0df9-47dd-ad9f-1396ccedb476.png)

TailwindCSSもレスポンシブ対応はできます。
しかもより簡単に。




通常のCSSでレスポンシブ対応をしようとすると
```css:CSSのレスポンシブ
@media (min-width: 768px) {
  .card {
    display: flex;
    justify-content: center;
  }
}
```
メディアクエリでブラウザサイズによって表示を切り替えますが、
TailwindCSSだと`sm`などのプレフィックスをつけて表現します。

```html
<div class="md:flex md:justify-center">
    <div class="md:shrink-0">
      <img
        class="w-full object-cover md:h-full md:w-48"
        src="/img/image.jpg"
        alt="sample image"
      />
    </div>
    <div class="md:shrink-0">
      <img
        class="w-full object-cover md:h-full md:w-48"
        src="/img/image2.jpg"
        alt="sample image"
      />
    </div>
</div>
```

| プレフィックス名 | 最小幅 | CSS |
|:-:|:-:|:-:|
| `sm`  |**40rem(640px)〜**| `{ @media (width >= 40rem) { ... }` |
| `md`  | **48rem(768px) 〜**|`@media (width >= 48rem) { ... }`|
| `lg`  |  **64rem(1024px) 〜**|`@media (width >= 64rem) { ... }` |
| `xl`  |  **80rem(1280px) 〜** |`@media (width >= 80rem) { ... }` |
| `2xl`  |  **96rem(1536px) 〜**|`@media (width >= 96rem) { ... }` |

これだけでも十分対応できるのではと思います。
`sm`や`md`は〇〇px〜で、**モバイルファースト（スマホレイアウトを基準とした）** ですが
デザインの作成方法によっては〜〇〇pxの**デスクトップファースト**の方がやりやすいかもしれません。（PCレイアウトしかできてないけど、コーディングスタートすることはあります）

その場合もTailwindCSSは用意していて、`max-sm`や`max-md`など **max-** がついています。

| プレフィックス名 | 最大幅 | CSS |
|:-:|:-:|:-:|
| `max-sm`  |**〜 40rem(640px)**| `{ @media (width < 40rem) { ... }` |
| `max-md`  | **〜 48rem(768px)**  |`@media (width < 48rem) { ... }`|
| `max-lg`  | **〜 64rem(1024px)** |`@media (width < 64rem) { ... }` |
| `max-xl`  | **〜 80rem(1280px)** |`@media (width < 80rem) { ... }` |
| `max-2xl`  |**〜 96rem(1536px)** |`@media (width < 96rem) { ... }` |

こちらだと`max-sm`とする場合、スマホレイアウトとなります。
どちらを使うのかはチームのスタイルによって変わってくるのかなと思います。

:::note info
TailwindCSSは **1rem（16px）** を基本としています。0.25remずつになっていて、`p-1`から`p-2`になると4px違います。1remベースにより、アクセシビリティの向上やデザインの一貫性につながります。
:::

### ホバーとかの時はどうするの？
TailwindCSSでは`hover`プレフィックスを使って表現できます。

例として、よくあるカーソルを合わせるとボタンが薄く透ける表現をしてみましょう。

```html:HTML
<button class="hover-button">ボタン</button>
```
```css:CSS
.hover-button {
                background-color: blue;
                color: white;
                transition: 0.3s;
                }
.hover-button:hover {
                opacity: 0.7;
                }
```

通常のCSSで書くとこうなりますが、TailwindCSSで書くとこうなります。

```html:TailwindCSSのホバー
<button class="bg-blue-500 text-white transition-opacity duration-300 hover:opacity-70">ボタン</button>
```

```html:抜粋
<button class="hover:opacity-70">
```

**opacityの70%** だから`opacity-70`です。こう見ると直感的に書けそうな気がしてきませんか？

### Shadowの表現は？
![sports_boxing_shadow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111652/84f1b584-34ff-4e4f-82d8-e7f62c7ba561.png)

今どきのデザインだとほんのりとシャドウが入っていたりと、有機的な雰囲気を作る上では欠かせない表現方法かと思います。

シャドウにはボックスシャドウとドロップシャドウがあり、表現したいものによって使い分けをされているかと思います。
TailwindCSSではボックスシャドウも、ドロップシャドウも表現することが可能です。


ボックスシャドウを使用する場合は
```html
<div class="shadow-lg bg-cyan-500">
ボックスシャドウ
</div>
```
のように`shadow-`を使います。

ドロップシャドウの場合は
```html
<div class="drop-shadow-md bg-yellow-500">
ドロップシャドウ
</div>
```
のように`drop-shadow-`を使います。

#### 影の色
シャドウを使用する場合、ボタンなどの要素にあった影の色を指定するかと思います。
TailwindCSSで影の色を変えるには、`shadow-blue-500`のように`shadow-`の後に色を指定します。

```html:影の色
<button class="text-white bg-red-700 shadow-md shadow-red-500/30">赤い影のボタン</button>
```
これで赤い影がつきます。
注意しないといけないのは、`shadow-red-500/30`だけではシャドウがつきません。
`shadow-md`などの影の大きさを指定しましょう。
これはdrop-shadow`も同様です。

色の指定のところで`500/30`と **/30**がありますが、これはopacityを指定しています。
つまり、`opacity: 0.3`ですね。

#### 影のカスタマイズ
影をつけられるのはわかったけど、Figmaのデザインと比べるとなんか違うんだよね。。ってなるかと思います。

```html:影のカスタマイズ
<div class="shadow-[0_4px_16px_rgba(51,51,51,0.3)]">
  ボックスシャドウカスタマイズ
</div>
```
`shadow-[]`内に通常の`box-shadow`で指定する値を入力すると影の方向などをカスタマイズできます。

同じ表現のボックスシャドウはいろんなところで使うし、しかも少し見づらいなと思ったかもしれません。。
そんなときはtheme変数を使用してプロジェクト内のボックスシャドウ、ドロップシャドウのユーティリティをカスタマイズしましょう。

`theme.css`などのCSSファイルに`@theme　{}`として、追加したいユーティリティクラスを定義していきます。


```css:@theme
@import "tailwindcss";

@theme {
  /* カスタムシャドウ */
  --shadow-custom-light: 0 2px 12px rgba(0, 0, 0, 0.08);
  --shadow-custom-medium: 0 4px 16px rgba(0, 0, 0, 0.12);
  --shadow-qiita: 0 6px 24px rgba(59, 130, 246, 0.25);
  --shadow-special: 0 12px 40px rgba(59, 130, 246, 0.35);
  
  /* カスタムフォント */
  --font-sans: "Inter", sans-serif;
  --font-mono: "IBM Plex Mono", monospace;
  
  /* カスタムカラー */
  --color-brand: #1c64f2;
  --color-brand-light: #3b82f6;

}
```

theme変数にはshadow以外にも定義することができ、プロジェクトでよく使う色などを定義しておくと便利です。

### グラデーションもできるの？
![flower_rose_rainbow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111652/60f7b969-912b-4575-bc49-073da43e03cf.png)


グラデーションも簡単にできます。
線形グラデーションを作成するには、`bg-linear-to-r`などのグラデーションの方向と`from`と`via`、`to`の色を指定します。


```html:グラデーション
<!-- 基本の線形グラデーション -->
<div class="bg-linear-to-r from-blue-500 to-purple-600">
  左から右へのグラデーション
</div>

<!-- 上から下へ -->
<div class="bg-linear-to-b from-blue-500 to-purple-600">
  上から下へのグラデーション
</div>

<!-- 斜め -->
<div class="bg-linear-to-br from-blue-500 to-purple-600">
  左上から右下へのグラデーション
</div>

<!-- ３色 -->
<div class="bg-linear-to-r from-indigo-500 via-purple-500 to-pink-500">
  ３色のグラデーション
</div>

<!-- グラデーションの位置 -->
<div class="bg-linear-to-r from-indigo-500 from-10% via-sky-500 via-30% to-emerald-500 to-90%">位置を調整したグラデーション</div>
```


### beforeとか擬似要素はどうするの？
スタイリングしていると擬似要素がないとできないデザインなども多く経験します。
TailwindCSSでどうやったら`before`が使えるのかイメージがつきませんでした。

#### beforeとafter

こんな感じで直感的に書くことができます。
```html:beforeとafter
<div class="before:content-['before'] before:text-amber-500">
  擬似要素
</div>

<div class="after:content-['after'] after:text-green-500">
  擬似要素
</div>
```

`before`や`after`を使って`after:content['*']`などと通常のCSSのイメージで使用できます。

:::note info
TailwindCSSは`content: ''`をデフォルトで自動的に追加するため、別の値が必要な場合を除き、指定する必要はありません。
:::

#### 他の疑似要素
`hover:`や`before:`、`after:`以外にも疑似要素のプリフィックスは用意されています。

```html:first:
<!-- リストの最初と最後 -->
<ul>
  <li class="first:border-t-0 last:border-b-0 border-t border-gray-200 pt-4">アイテム1</li>
  <li class="first:border-t-0 last:border-b-0 border-t border-gray-200 pt-4">アイテム2</li>
  <li class="first:border-t-0 last:border-b-0 border-t border-gray-200 pt-4">アイテム3</li>
</ul>
```

```html:active
<!-- ボタンのクリック時 -->
<button class="bg-cyan-500 hover:bg-cyan-600 active:bg-cyan-700 active:scale-95 transition-all">
  クリック時に縮む
</button>
```

## ディレクティブを使ってもっと使いやすく
これまでで、「へー、TailwindCSSって色々できんじゃん」って思っていただけたかと思います。

少しだけ紹介したテーマ変数についてもう少しお話しします。

> 同じ表現のボックスシャドウはいろんなところで使うし、しかも少し見づらいなと思ったかもしれません。。
そんなときはtheme変数を使用してプロジェクト内のボックスシャドウ、ドロップシャドウのユーティリティをカスタマイズしましょう。

にあるように、カスタマイズしたい値を使い回す際に便利です。

TailwindCSS V4になってからCSSに書くようになり、とてもシンプルでわかりやすくなりました。
TailwindCSS V3以前では、カラーや値を定義したいときは`tailwind.config.js`で拡張する必要する必要がありました。

```javascript:tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        primary: '#3b82f6',
        secondary: '#64748b',
        brand: {
          50: '#f0f9ff',
          500: '#0ea5e9',
          900: '#0c4a6e'
        }
      },
      spacing: {
        '18': '4.5rem',
        '88': '22rem'
      }
    }
  }
}
```

実際に使用する場合は、

```html:
<div class="bg-primary text-brand-500 p-18">
  コンテンツ
</div>
```

これがV4になってからはCSSファイルにCSS変数を使って定義できるようになりました。

```css:theme.css
@theme {
  --color-primary: #3b82f6;
  --color-secondary: #64748b;
  --color-brand-50: #f0f9ff;
  --color-brand-500: #0ea5e9;
  --color-brand-900: #0c4a6e;
  
  --spacing-18: 4.5rem;
  --spacing-88: 22rem;
  
  --font-size-xs: 0.75rem;
  --font-size-sm: 0.875rem;
}
```

実際に使うときは（同じですが）
```html
<div class="bg-primary text-brand-500 p-18">
  コンテンツ
</div>
```

すごくわかりやすくなりました。

`@theme`はディレクティブというものの１つで他に`@apply`や`@utility`、`@layer`、`@variant`、`@config`などがあります。

特に使うであろう`@apply`と`@utility`、`@layer`をご紹介します。

### `@apply`ディレクティブ
`@apply`ディレクティブは通常のCSSクラスにTailwindCSSのユーティリティクラスを適用することができる便利なディレクティブです。

例えば
```css:@apply
/* 通常のCSSにTailwindCSSを適用 */
.card {
    @apply bg-blue-500;
    clip-path: circle(50% at 50% 50%);
}
```
とすると、TailwindCSSのユーティリティを使いつつ、clip-pathで丸に切り抜いたクラスを作成することができます。

TailwindCSSのユーティリティクラスとTailwindCSSではできないCSSを組み合わせたクラスを作ることも魅力ですが、単純にユーティリティクラスを一つのクラスにまとめられることが一番の魅力かもしれません。

```css:ユーティリティクラスをまとめる
.button-primary {
  @apply bg-green-300 hover:bg-green-500 border-solid border-2 border-green-400;
  @apply shadow-md hover:shadow-lg;
  @apply px-4 py-2 rounded transition-colors duration-200;
}
```
```html
<button class="button-primary">クリック！</button>
```

これによりHTMLのコードをスッキリわかりやすくすることが可能になります。
また、機能ごとにグループ化することで整理しやすく、変更する場合もわかりやすいです。

### `@utility`ディレクティブ
`@utility`ディレクティブは`@apply`ディレクティブと似ているのですが、`@apply`はCSSクラスを作るディレクティブに対して、`@utility`はユーティリティクラスを作るディレクティブです。

#### クラス作成の違い
| | `@apply` |`@utility` |
|:-:|:-:|:-:|
|  クラスタイプ |　通常のクラス | ユーティリティクラス|
|  修飾子 |　❌ | ⭕️|
|  レイヤー | components  | utilities |

`md:`などの修飾子は通常のクラスには使用できません。しかし、`@utility`ディレクティブで作成するクラスはTailwindCSSユーティリティクラスのため、使用できます。

```css:@utilityの構文
@utility クラス名 {
  /* CSSプロパティ */
}
```

```css:例
@utility text-regular {
    font-size: 1rem;
    font-weight: 500;
    line-height: 1.25;
}
```
```html
<!-- 他のTailwindクラスと組み合わせ -->
<p class="text-regular text-gray-700 mb-4">
  テキスト
</p>

<!-- 修飾子も使える -->
<p class="text-regular md:text-lg hover:text-blue-600">
  レスポンシブ対応テキスト
</p>
```

また、`@apply`ディレクティブは通常クラスを作成するときだけでなく、`@utility`ディレクティブの中で使用することもできます。

```css:@applyを@utilityで使う
@utility button-scale {
  @apply transition-transform duration-150;
  
  &:active {
    @apply scale-95;
  }
}
```

特定のコンポーネントで使うなら、`@apply`でまとめたクラスを作成し、いろんなところで使うものをまとめたいときは`@utility`でまとめたユーティリティクラス作成するのが使い分けとして良さそうです。

### `@layer`ディレクティブ
通常、CSSだと上から順番に読まれるため、
```css:通常のCSS
.qiita {
    color: yellow;
    color: blue;
}
```

とあった場合、colorはblueが適用されます。
そのイメージで
```html
<div class="text-yellow-500 text-blue-500">Tailwind</div>
```
と、テキストのカラーに対するユーティリティクラスをつけたときに、**blueにならない！**となることがあります。TailwindCSSではCSSファイル内での定義順序によって優先順位が決まるようです。

「あ、色これにしてみるか」と、追加したり、paddingを変更したりしても変わらないってことが起こりえます。

```html:!importantを使う
<div class="!text-blue-500 text-yellow-500">Tailwind</div>
```

`!important`を使えば、それが適用されますが、あまり好ましくはありません。

`@layer`ディレクティブを使えば、優先順位を制御することが可能になります。
`@layer`には３つのレイヤーがあり、`base`、`compotnets`、`utilities`の順に強くなります。

一番弱い`base`はリセットCSSを書いて、書き換わっても良いものにするなど、用途に応じて使い分けると良いのかなと思います。

#### 優先順位

| 順位 | レイヤー |　用途　| 
|:-:|:-|:-|
| 1  | **`!important`** | 強制 |
| 2  | **`@layer utilities`** | カスタムユーティリティクラス |
| 3  | **`TailwindCSSユーティリティ`** | 通常のTailwindユーティリティクラス |
| 4  | **`@layer components`** | コンポーネント |
| 5  | **`@layer base`** | リセットCSS、基本スタイル |


```css
/* リセットCSS */
@layer base {
  * { margin: 0; padding: 0; }
}

/* コンポーネント */
@layer components {
  .card { @apply bg-white p-4 rounded; }
}

/* 通常のユーティリティクラス */
/* .text-lg, .bg-blue-500 など */

/* カスタムユーティリティクラス */
@layer utilities {
  .text-brand { color: #ff6b6b; }
}

/* 強制 */
<div class="!bg-red-500">important</div>
```

## TailwindCSSって使えそうじゃん
TailwindCSSはなんかごちゃごちゃしてて、なんか微妙だなと思っていましたが調べていくうちに結構機能も充実してて使えそうだなと思うようになりました。

グラスモーフィズムやニューモフィズムみたいな表現もできます。
（ちょっと複雑なCSSはそもそもジェネレーターで作るとは思いますが。。）

https://tailwind-gradient-generator.vercel.app/

Reactのコンポーネントにスタイルを当てる方法で、`CSS in JS`や`shadcn/ui`などのUIコンポーネントなどありますがしっくりこず、ずっと残りそうな気が個人的にしませんでした。

その中でTailwindCSSはフレームワークに標準で入っているものも出ていたり、いろんな方がTailwindCSSを採用していると話しているのを聞いてちょっと調べてみようと思いました。

CSSをガンガン書いていた自分にとっては使いやすそうで、手に馴染むくらいまで使い込んでみたいと思います。

AIを使ってスタイリングを作成することも多くなってきている時代かと思いますが、細かい修正をするのは人間ですし、使いこなせるに越したことはないです。

最後までお読みくださり、ありがとうございます。
これを機会にTailwindCSSを触ってみていただけたら嬉しいです。
(CDNもあります。本番環境では一応、非推奨のようですが。）
```html
 <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
 ```

### 参考記事・サイト
https://qiita.com/Takazudo/items/78ee15564bfefdea844c#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB

https://qiita.com/GMR0009/items/0d6b4f9d81b7e6bff6e9

https://qiita.com/70ki8suda/items/b95aeb4d4d3cab57a8fe

https://tailwindcss.com/docs/installation/using-vite

![text_kansya.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1111652/3b979a8e-fe1d-4b32-aea9-8e89c326bdea.png)