TailwindCSS と比べつつ Chakra UI に入門する

# 背景

さまざまなCSS フレームワークが登場し、最近は Tailwind CSSが注目され話題になっていたのは認識していました。そんな中、一部でChakra UIなるものの名前も見るようになり、さらにTailwind CSSと比較される書き方をされることが多いように感じ気になっていました。

また、React Developer Roadmap2021の Stylingにあり、使ってみたいと思っていたのもあります。

![スクリーンショット 2021-10-05 16.34.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528613/f910247a-912f-8eb5-49a7-be9190ad01f5.png)
参考： https://roadmap.sh/react

私はReact を使用する場面が業務でも個人開発でも多いのですが、個人的にReact UserはChakra UI推しが多いように感じたのも使ってみようと思った理由の一つです。
https://www.reddit.com/r/nextjs/comments/jznkit/tailwindcss_vs_chakra_ui_for_fast_development/

そもそもChakra UIとはどういったものなのか、Tailwind CSSとの違いは何だろうかと興味をもち、今回使ってみました。


# Chakra UI とは

emotionに依存しているReact のUIコンポーネントライブラリ。
シンプルでモジュール化されたアクセス可能なコンポーネントライブラリで、Reactアプリケーションを構築するために必要なビルディングブロックを提供します。

https://chakra-ui.com/

上記ですと、直訳的な感じが強すぎるので簡単に言うと

> emotionに
Tailwind CSS の直感性と柔軟性足し合わせた
Pure typescript な Best practice React component集

参照: はるさめさん @spring_raining

だそうです。後者の言い回しの方がわかりやすかったので引用させていただきました。

# Tailwind CSSと比べる Chakra UI

背景でも述べたように Chakra UI とTailwind CSSは度々同時に話される場面を最近見かけるので自分なりに共通点と相違点をまとめてみました。

## Tailwind CSS との共通点

- Utility first であるという点
- Themeの記法

の2点が挙げられると思います。

### Utility first であるという点

Utility firstとは？ となる方もいらっしゃるかもしれないので簡潔に説明します。以下Tailwind CSSを例に紹介します。
Tailwind CSSのdefault themeを見たことのある人でしたらわかると思うのですが、
`text-gray` を例に取ると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528613/30e16833-59ab-e7a8-ae47-e75cbc9604a9.png)

のように用意されていたり、
Font sizeのようなpropertyに関しても

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528613/f042992d-8de9-dc0e-cab5-eca357cc0f45.png)

といったように用意されています。
このようなdefault themeは、開発の際の意思決定のコストを節約してくれます。CSSは使わずにTailwind CSSが提供しているクラスを使用してのスタイリングが可能であるということからUtility firstと言います。


またクラスといったような定義グループを作れ、そこからピックアップすることで、開発チーム内でテーマ統一が簡単にできます。スタイルガイドやデザインシステムの構築を可能にしており、またこれらのカスタマイズが簡単にできるという利点を持っています。
Tailwind CSSの例で話しましたが、Chakraに関してはここは同じです。Themeの柔軟さは両者同じく持ち合わせています。

### Themeを用いた記法

上でも少し触れましたが、Chakra UIもTailwind CSSも default themeを持っており、それらを利用してstylingが可能です。以下にサンプルコードを示していますが、指定の仕方も似ています。

- Tailwind CSS
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528613/e9d7c4c6-2eb9-3065-4868-9144ad674c69.png)

- Chakra UI
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528613/da9c656c-2abc-f8eb-af3b-bc79943ec119.png)


## Tailwind CSS との違い
Tailwind CSSと Chakra UIの相違点について表にまとめてみました。

||Tailwind CSS  |Chakra UI  |
|---|---|---|
|既存prjへ導入しやすさ|導入しやすい  |導入しづらい  |
|デフォルトのスタイルを持ったコンポーネントを提供しているか|提供していない  |提供している  |
|Style Overrides|特定のclassNamesをオーバーライドしたり、カスタムCSSを書いたりする最善の方法を見つけ出す必要がある|Chakra UIのスタイルはpropsベースなので、オーバーライドはpropsを渡すだけで簡単にできます|
|学習コスト|Tailwind CSSで用意されている定義済みのクラスを学ぶ必要がある|attributeのsuggestがあるので楽|
|型保護されているか|typescriptで型保護されていない(ライブラリを入れれば可能)|typescriptで型保護されている|


# Chakra UIの推しポイント
個人的にChakra UIを使っていて良いと感じる推しポイントを紹介します。

### Pure typescriptでcomponentが定義されている

以下の画像だとわかりづらいので実際に試してみてほしいのですが、VSCode使用時に自然な感じでattributeを設定でき、書いている体験が非常に良いです。また型保護されているので安心ですね。これはChakra UIの売りの一つみたいなものです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528613/9a25b137-a825-9be3-64dd-8b7981a144e9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528613/2d0bbaac-c9ac-6ec6-84b7-15669e8c8de3.png)

### Style付きのコンポーネントが便利
ButtonやInput、Sliderみたいなコンポーネントが揃っているのですぐに組み立てることができます。プロトタイピングをする際、便利だなと感じます。propsを渡すだけでstyleを簡単に切り替えられるのも嬉しいです。

例） Buttonコンポーネント
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528613/120228af-2ec1-3635-a2b2-82135df0a2a0.png)

### Modal等の複雑なコンポーネントも用意されてる
Modalは素で実装すると割と手間だと思いますが、こう言ったちょっと自前で実装すると面倒なものがすでに用意されており importするだけで使用することができます。
個人的にAction MenuやDrawer、Tooltipみたいなのが揃っているので嬉しいです。(欲を言えばカルーセルも欲しかったのですが未実装でした。)
参照： https://chakra-ui.com/docs/getting-started

### Hooksも用意されている
useClipbordやuseBreakPointValueといったHooksが提供されています。

```jsx:clipbord.tsx

// useClipbordの使用例
function Example() {
  const [value, setValue] = React.useState("Hello world")
  const { hasCopied, onCopy } = useClipboard(value)

  return (
    <>
      <Flex mb={2}>
        <Input value={value} isReadOnly placeholder="Welcome" />
        <Button onClick={onCopy} ml={2}>
          {hasCopied ? "Copied" : "Copy"}
        </Button>
      </Flex>
      <Editable placeholder="Paste here">
        <EditablePreview width="100%" />
        <EditableInput />
      </Editable>
    </>
  )
}

```

### CSS in JS としての機能
styled systemを内包しているので、emotionやstyled-componentsを書いていた人は親しみのある書き方が可能です。

```jsx
const StyledBox = styled(Box)`
    background: "#FFFFFF";
    padding: "48px";
    margin: "64px";
`; 

// ~省略~
        <StyledBox>HogeHoge</StyledBox>
      </Flex>
    </>
  )
};
```

### カスタマイズ可能な設計システム

基本的にはPropsを利用したStyle設定で良いですが、コンポーネントの再利用という観点でテーマ機能を用いることもできます。Next.jsを使用する場合は`_app.tsx`にProviderを設置します。

```tsx:_app.tsx
const MyApp: React.VFC<AppProps> = ({ Component, pageProps }) => {
    const router = useRouter();
    const theme = router.pathname.startsWith('/admin')
        ? adminTheme
        : normalTheme;
    return (
        <ChakraProvider theme={theme} colorModeManager={localStorageManager}>
            <RecoilRoot>
                <Component {...pageProps} />
            </RecoilRoot>
        </ChakraProvider>
    );
};
```

Themeの指定については以下のようにtheme用のファイルを作成しておき、呼び出すとわかりやすいです。

```ts:extendTheme.ts
export const normalTheme = extendTheme({
    ...config,
    breakpoints,
    colors: {
        text: {
            primary: '#FFFFFF',
            secondary: '#559DEB',
        },
        bg: {
            primary: '#559DEB',
            secondary: '#FFFFFF',
        },
        border: {
            primary: '#FFFFFF',
        },
    },
});

```

## 入門してみてのChakra UIのもやっとポイント
- CSSセレクタを使って複雑にstylingする場合は向いていない。
(styled()でできなくはないけどstyledを使う必要が出てきてしまう点)

- 汎用コンポーネントが多いのできちんと使おうとすると最初コストがかかる。

- Style付きcomponentなのが逆に嫌な場合もある。

- extendThemeは作りきればその後は早いかもしれないが作成に時間がかかる。変更範囲が増えそう感。

# 終わりに
もやポイントもありますが個人的には使いやすいという印象です。作るアプリケーションによっては向き不向きがあるとは思うのでプロダクトによって採用するかどうかは変わりそうだなと思います。ですがハマれば開発速度上がりそうなので良いと思います。
個人的にThailwind CSSよりも学習コスト低めに感じるのですぐ導入できるところも嬉しい点です。
今回の内容は一部しかChakra UIを紹介できませんでしたが、他にもデフォルトでダークモードに対応するなど、様々な機能を有しているので、ちょっとでも気になる方は是非使ってみて欲しいです。

# 参考資料
- https://chakra-ui.com/docs/getting-started
- @spring_raining
- https://roadmap.sh/react
- https://zenn.dev/terrierscript/articles/2021-05-11-chakra-ui-component-extends