TS×React styled-componentsとTailwind CSSを使ってみての感想

# 投稿目的
<ul>
<li>Reactにおけるスタイル適用に関する知見を有識者から得たい</li>
</ul>



# 本記事について
今年4月から、`Tailwind CSS`を使っている現場(Typescript×React)に配属されました。
一方で、今年4月から始めた個人開発(Typescript×React)においては、`styled-components`を採用しています。
2つのパッケージを使ってみて、双方に良い点があったため比較形式でご紹介したいと思います。



# 比較
## 環境構築について
### styled-components
```bash
$ yarn add -D styled-components
```
上記コマンドでインストールすると`package.json`に`styled-components`が追記されます。
これで準備は完了です。
``` package.json
    ...
	"devDependencies": {
		"styled-components": "^6.1.8",
        ...
	},
     ...
```
:::note info
・1コマンドで完了!
:::

### Tailwind CSS
`Tailwind CSS`の環境構築については、下記記事で紹介しております。`styled-components`に比べると手間がかかる印象です。

https://qiita.com/ko-sato-primebrains/items/36cfdaf7acc21ea8f450

:::note info
・DaisyUIなどの関連パッケージも多数! 簡単にスタイリッシュなスタイルにできる!
:::
:::note warn
・アプリケーション起動時、スタイルが適用されるようにビルドを実行する必要あり。
:::

#### どっちが楽?
環境構築は`styled-components`の方が簡単そうです。


## 書き方について
フレックスボックスで要素を縦横中央ぞろえにしてみます。
また、第二段階として`isVisible`という変数によってスタイルを動的に変えてみます。

### styled-components
```CenteredFlexBox.tsx
import React, { ReactNode, FC, memo } from "react";
import styled from "styled-components";

type CenteredFlexBoxProps = {
	children: ReactNode;
};

export const CenteredFlexBox: FC<CenteredFlexBoxProps> = memo(({ children }: CenteredFlexBoxProps) => {
	return <SContainer>{children}</SContainer>;
});

const SContainer = styled.div`
	display: flex;
	flex-direction: column;
	justify-content: center;
	align-items: center;
`;
```
※`SContainer`の定義位置は任意の場所で構いません。名称も任意です。

`styled-components`は、スタイルを適用した要素を定義し、その要素を`React.FC`の中で用いることによってスタイルをあてることができます。
文法としては、`styled.[用いたい要素名(div, a, spanなど)]`の後に``(バッククオート囲み)を付し、バッククオート囲みの中にCSSを記述していきます。
CSSをCSSの文法のまま`.jsx/.tsx`ファイルの中に記述できます。

定義位置や変数名は自由に設定できますが、規則を定めないとカオスになりがちです。
私の場合、「`styled-components`で定義した要素は、先頭を`S`から始める」「定義位置はファイルの末尾にする」というように規則を定めています。

次に、動的にスタイルを変化させられるようにしてみます。
```CenteredFlexBox.tsx
import React, { ReactNode, FC, memo } from "react";
import styled from "styled-components";

type CenteredFlexBoxProps = {
	children: ReactNode;
    isVisible: boolean;
};

export const CenteredFlexBox: FC<CenteredFlexBoxProps> = memo(({ children, isVisible }: CenteredFlexBoxProps) => {
	return <SContainer isVisible={isVisible}>{children}</SContainer>;
});

type SContainerProps = {
    isVisible: boolean;
}

const SContainer = styled.div<SContainerProps>`
	display: flex;
	flex-direction: column;
	justify-content: center;
	align-items: center;
    visibility: ${(props) => (props.isVisible ? "visible" : "hidden")};
`;
```
`CenteredFlexBox`のPropsである`isVisible`を`SContainer`にも渡すことでスタイルを動的に変化させることができます。

:::note info
・CSSの文法のまま、CSSを`.jsx/.tsx`ファイルに記述できる!
・動的なスタイル変更もスタイリッシュに記述できる!
:::
:::note warn
・記述量が多くなってしまう...
:::

### Tailwind CSS
```CenteredFlexBox.tsx
import React, { ReactNode, FC, memo } from "react";

type CenteredFlexBoxProps = {
	children: ReactNode;
};

export const CenteredFlexBox: FC<CenteredFlexBoxProps> = memo(({ children }: CenteredFlexBoxProps) => {
	return <div className='flex flex-col justify-center items-center'>{children}</div>;
});
```

`Tailwind CSS`は、スタイルを適用したい要素の`className`属性に対応するclass名を設定することでスタイルをあてることができます。
コードの記述量としては、`styled-components`と比較してかなりすっきりした印象です。

こちらも、動的にスタイルを変化させられるようにしてみます。
```CenteredFlexBox.tsx
import React, { ReactNode, FC, memo } from "react";

type CenteredFlexBoxProps = {
	children: ReactNode;
    isVisible: boolean;
};

export const CenteredFlexBox: FC<CenteredFlexBoxProps> = memo(({ children, isVisible }: CenteredFlexBoxProps) => {
	return (
       <div className={`flex flex-col justify-center items-center${ isVisible ? " visible" : " invisible"}`}>
         {children}
       </div>
    );
});
```
`className`属性にテンプレートリテラルを設定し、`isVisible`によって適用されるclass名が`visible / invisible`のどちらかに変化するようにすることができます。

ちなみに、`width`や`padding`を`px`単位で設定したい場合は下記にように`className`属性を設定します。
``` CenteredFlexBox.tsx
// widthを1200px、左右のpaddingを30pxに設定
// 上下のmarginは、0.75rem(12px)に設定
return <div className='w-[1200px] px-[30px] my-3 flex flex-col justify-center items-center'>{children}</div>;
```

:::note info
・`className`属性をいじるだけでスタイルを適用できる!
:::
:::note warn
・コードが煩雑になりがち...
・学習コストがかかってしまう...
・細かいスタイル管理が難しいかも...
:::

### どっちが楽?
記述量としては`Tailwind CSS`の方がかなり少ないですね。
また`DaisyUI`のようなプラグインを使うと、`className`属性を編集するだけでスタイリッシュなデザインにすることができます。
ただし、適用したいCSSが多くなってくると`className`属性が長くなり、コードが煩雑になってしまう可能性もあります。
`styled-components`はCSSの文法のまま記述できる点、既にある程度CSSを書ける方の学習コストは低そうです。
また、動的にスタイルを変化させる際も、スマートに記述することができます。

どちらが楽か、一概には言えませんが... 
個人的にはCSSを文法そのままに記述できる`styled-components`の方が楽しい+分かりやすくて好きです。


## VSCodeとの相性について
### styled-components
`vscode-styled-components`というプラグインを用いると、`styled-components`を記述する際に自動補完を用いることができます。
また、ホバーするとCSSの情報を表示してくれるようになります。

https://marketplace.visualstudio.com/items?itemName=styled-components.vscode-styled-components

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3519885/9996eb80-c961-a72b-d7ea-02ec65f12dc9.png)

### Tailwind CSS
`Tailwind CSS IntelliSense`というプラグインを用いることで、こちらも自動補完を用いることができます。
ホバーすると「このclassにはどんなCSSが設定されているか?」を表示してくれます。

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

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3519885/7c159795-afb1-60a9-19a8-bd05a3143605.png)


### どっちが楽?
VSCodeとの相性としては、どちらも申し分ないと思います。
ホバーした時の内容の充実度は`styled-components`に軍配が上がりそうです。

## 総評
### styled-components
:::note info
・環境構築が楽!
・CSSの文法のまま、CSSを`.jsx/.tsx`ファイルに記載できる!
・動的にスタイル制御もスタイリッシュに記述できる!
:::
:::note warn
・コードの記述量が増えがち...
・スタイリッシュなスタイルにしたい場合、別途`Material UI`などのパッケージをインストールした方がよいかも...
:::

### Tailwind CSS
:::note info
・`className`属性を編集するだけでスタイルを適用できる!
・`Daisy UI`のような`Tailwind CSS`を前提としたプラグインとの相性が良い!
:::
:::note warn
・環境構築が手間...
・複雑なスタイル適用は難しそう...
・動的なスタイル変化はテンプレートリテラルが必要...
:::



# まとめ
いかがだったでしょうか。
`Tailwind CSS`がデファクトスタンダート感はありますが、CSSをCSSの文法のまま記述できる`styled-components`は非常に楽しく、機能的でもあります。

おススメの`styled-components`/`Tailwind CSS`の活用法や、他のおススメのパッケージがありましたらご教示いただけると幸いです!