【Angular】Angularでtailwindを使う方法


![tailwindcss](https://tailwindcss.com/_next/static/media/tailwindcss-logotype.128b6e12eb85d013bc9f80a917f57efe.svg)

## 複雑な設定は@ngneat/tailwindに任せよう

[tailwindcssの公式](https://tailwindcss.com/)にある方法でAngularにtailwindをインストールしようとすると、設定が複雑すぎて難易度が高いです。今回は複雑な設定もほぼ行ってくれるモジュール[`@ngneat/tailwind`](https://www.npmjs.com/package/@ngneat/tailwind)を使って、実際にAngularで使えるようになったので、それについて書いていきたいと思います。

npm: [@ngneat/tailwind](https://www.npmjs.com/package/@ngneat/tailwind)

## @angular/materialを使う場合は先にインストール

Angular Materialを利用する方は`@ngneat/tailwind`より先に`@angular/material`をインストールする必要があります。順序が逆になると、衝突が起こり`@angular/material`のインストールに失敗します。

```shell
> ng add @angular/material
```

## @ngneat/tailwindをインストール

次のコマンドで`@ngneat/tailwind`をインストールします。


```shell
> ng add @ngneat/tailwind
```

ただし、angular cliのバージョンが11.1.0未満の場合は`@ngneat/tailwind`のバージョンを5.2.5に指定する必要があるようです。

```shell
> ng add @ngneat/tailwind@5.2.5
```

すると次のようなメッセージが出てくるので、必要に応じて回答していきます。

```shell:質問1
? Would you like to enable dark mode? (Use arrow keys)
> none
  class
  media
```

特になければ自分は`none`にしています。

```shell:質問2
? Would you like to use tailwind directives & functions in component styles? (might increase build time) (y/N) 
```

特になければ自分は`N`にしています。

```shell:質問3
? What @tailwindcss plugins do you want to enable? (Press <space> to select, <a> to toggle all, <i> to invert selection)
>( ) aspect-ratio
 ( ) forms
 ( ) line-clamp
 ( ) typography
```
ここでチェックを付けた場合、`tailwind.config.js`に選択したプラグインが追加されます。とりあえず自分はすべてチェックしています。

```javascript:tailwind.config.js
...
    plugins: [
      require('@tailwindcss/aspect-ratio'),
      require('@tailwindcss/forms'),
      require('@tailwindcss/line-clamp'),
      require('@tailwindcss/typography')
    ],
...
```

インストールが完了すると、`tailwind.config.js`と`webpack.config.js`が新規作成されます。
これで問題がなければさっそくtailwindcssをAngular上で使えるようになっているはずです。

## VSCodeにおすすめの拡張機能

[Tailwind CSS IntelliSense](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss)

htmlにてタグのclassを記述する際に、tailwindで利用できるクラスの候補を表示してくれます。併せて入れておくと便利です。（画像は上のサイトより引用）

![autocomplete.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505645/da08d6fa-4a81-e72c-beff-a02d8fb0765a.png)

## 使ってみる

検証用にAngularアプリケーションを新規作成し、`@angular/material`と`@ngneat/tailwind`インストールしました。
次のテンプレート`app.component.html`を例に、tailwindのクラスを追加してみたいと思います。

ちなみに、記述できるtailwindのクラスは[公式のドキュメント](https://tailwindcss.com/docs/display)が見やすいです。cssを読める方は比較的すぐに使えると思います。

まずスタイル無しの状態がこちらです。

```html:app.component.html
<div>
  <div>
    <div>
      <p>
        Is it OK?
      </p>
    </div>
    <div>
      <div>
        <button>
          OK
        </button>
      </div>
      <div>
        <button>
          Cancel
        </button>
      </div>
    </div>
  </div>
</div>
```

実行結果はこんな感じです。

![tailwind1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505645/38898852-8c47-b8ee-36e8-9b101d6c1a24.png)

そしてtailwindでスタイルを追加したものがこちらです。

```html:app.component.html
<div class="h-screen w-screen pt-6 bg-gray-50">
  <div class="w-48 h-48 mx-auto flex flex-col justify-evenly bg-white shadow overflow-hidden sm:rounded-lg">
    <div app-text class="mx-auto text-2xl font-medium">
      <p class="w-full h-full align-middle text-center">Is it OK?</p>
    </div>
    <div class="mx-auto flex flex-row content-center justify-center">
      <div class="w-16 h-10 mr-4">
        <button class="w-full h-full border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-yellow-600 hover:bg-yellow-700 focus:outline-none focus:ring-2 focus:ring-black">
          OK
        </button>
      </div>
      <div class="w-16 h-10">
        <button class="w-full h-full border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-black">
          Cancel
        </button>
      </div>
    </div>
  </div>
</div>
```

実行結果はこちらです。

![tailwind2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505645/abdad5b0-80d8-b2e5-9c49-233b23d825f0.png)

このように、cssにスタイルを記述することなくhtmlのみでスタイルを表現することができるようになりました。

### 余談

一見、htmlにすべてのスタイルを記述するのは煩雑になって大変に見えますが、これはコンポーネント設計によって解決できると考えています。（コントロールの見た目に関するスタイルは子コンポーネントに担当させ、marginやflexなどのレイアウトに関するスタイルは親コンポーネントに担当させるという使い方で、これによりレイアウトに関するスタイルを都度cssファイルに記述したり、BEM記法のようにclass名を考えたりする必要がなくなり、作業効率が上がると期待しています）

関連記事: [【Angular】最適なコンポーネント設計について考えてみた: Page-Layout-Presenter構造](https://qiita.com/oioigohan/items/a6b700d67e9fa71ce9f7)