【CSS in JS】UnoCSSって知ってた？3年前にリリースされてたんやけど…

先日「Best of Js」の「CSS in JS」の一覧を見ていた時に「UnoCSS」というものを見つけました。

https://bestofjs.org/projects?tags=css-in-js&sort=total

「UnoCSS」以外は聞き覚えのあるものしかありませんでしたが、気になったので調べました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146612/03f51dc9-6c23-0df4-75df-22a963f2e44c.png)

:::note
今後の技術選定の選択肢になるかもしれないと思ったのでよろしければ参考にしてください！
:::

## UnoCSSとは？

UnoCSSは、WindiCSSのチームメンバーの1人によって開発が開始されました。
WindCSSはTailwindCSSからインスピレーションを受けて作成されています。

https://unocss.dev/

> UnoCSSは、柔軟性と拡張性を考慮して設計されたインスタントアトミックCSSエンジンです。コアは偏りがなく、すべてのCSSユーティリティはプリセットで提供されます。

とあります。

UnoCSSの背景などは作成者がブログに記載してくれています。

https://antfu.me/posts/reimagine-atomic-css

:::note
印象としては、TailwindCSSとはコンセプトが異なるとのことなので比較するのは難しいですが、カスタマイズが柔軟なTailwindCSSといったところかと思います。
:::

また、UnoCSSは様々なフレームワークやツールに対応しています！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146612/44bc8e0e-9385-6700-a1b8-a43b8fad5cea.png)

## UnoCSSを選ぶ理由

https://unocss.dev/guide/why

> 最も重要なのは、UnoCSS がアトミック CSS エンジンとして抽出され、すべての機能がオプションであるため、必要な機能の組み合わせで独自の規則、独自のデザイン システム、独自のプリセットを簡単に作成できることです。

ここから読み取れるのはかなり柔軟性の高いものであることが伺えます。

`TailwindCSS`と`WindiCSS`との互換性も考慮されています。
完璧ではないと説明にはありますが、「TailwindCSSで実装したけどもっと柔軟性を持たせたい」という場合に乗り換えを検討することも可能そうです！

https://unocss.dev/presets/wind#rules

## UnoCSSで使えるリセットCSS

UnoCSS単独で利用する場合いろんなリセットCSSが利用できるようです！

https://unocss.dev/guide/style-reset

```tsx:ドキュメントで定義されているリセットCSS
import '@unocss/reset/normalize.css'
import '@unocss/reset/sanitize/sanitize.css'
import '@unocss/reset/sanitize/assets.css'
import '@unocss/reset/eric-meyer.css'
import '@unocss/reset/tailwind.css'
import '@unocss/reset/tailwind-compat.css'
```

## UnoCSSの保守・運用

https://unocss.dev/integrations/eslint

ブラックリスト形式で利用できるユーティリティクラスを制限できるようです！

:::note
縛りすぎは逆に開発体験を損ねてしまいますが、柔軟な設計ではclassの利用ルールの統制が取れず煩雑化します。
eslintのような機構が用意されていることは喜ばしいです。
:::

vscodeたJetBrainsを利用している場合は拡張機能も用意されているようです！

https://unocss.dev/integrations/vscode

https://unocss.dev/integrations/jetbrains

## UnoCSSを試したい

UnoCSSを試したい場合Playgroundが用意されていますのでそちらで試せます！

https://unocss.dev/play/

## UnoCSSの良さそうなところ

### iconプリセットが用意されている

https://unocss.dev/presets/icons

SVGを利用していて、コードとは別にファイル管理しているのであれば改善できそうです！

### 属性モード

TailwindCSSはユーティリティクラスが重なると読みづらくなるというデメリットがあります…

```jsx:before
<button class="bg-blue-400 hover:bg-blue-500 text-sm text-white font-mono font-light py-2 px-4 rounded border-2 border-blue-200 dark:bg-blue-500 dark:hover:bg-blue-600">
  Button
</button>
```

属性モードを利用すると下記のようになります。

```jsx:after
<button
  bg="blue-400 hover:blue-500 dark:blue-500 dark:hover:blue-600"
  text="sm white"
  font="mono light"
  p="y-2 x-4"
  border="2 rounded blue-200"
>
  Button
</button>
```
TailwindCSSで冗長性を解消しようと思った場合`tailwind-variants`を利用していましたが、UnoCSSは属性モードで解消できるのは良いと思いました！

https://unocss.dev/presets/attributify#attributify-mode


### プレフィックス自己参照

冗長的な記述を解消するためのソリューションとしてこちらの機能も有効かと思いました。

```jsx:before
<button class="border border-red">
  Button
</button>
```

プレフィックス自己参照の機能を使うと下記のようになります！

```jsx
<button border="~ red">
  Button
</button>
```

先ほどの属性モードも同じですが、UnoCSS独特なので知らないと「ん？」っとなります。
チームでコミュニケーションが取れていれば手段の一つとして検討しても良いかと思いました！

https://unocss.dev/presets/attributify#prefix-self-referencing


### TypeScript(JSX/TSX)がサポートされている
当たり前のようにTypeScriptもサポートされています！

https://unocss.dev/presets/attributify#typescript-support-jsx-tsx

## まとめ
UnoCSSは2021年に登場したのですでに3年経っています。
完全にキャッチアップが遅れていたことは否定できないですが、今年に入ってからnpmのインストール数が増えているようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146612/47fc02b1-1922-afdc-1b56-a94f06fedc7c.png)

今年の3月ぐらいまではなだらかに増えてきておりましたが、それ以降ダウンロード数が一段上がっています。
ゆえに「Best of Js」でTOP5にランクインするほどにまでなったわけですね。

:::note warn
複雑な要件に対応するためには、柔軟なカスタマイズ性が必要ということかもしれません…
:::

今後の動向も追っていきたいと思います！