【CSS in JS】Qiitaで 👩‍🎤 Emotion を使っている理由

## はじめに
<!-- 30秒 -->
[Qiita株式会社 Advent Calendar 2022](https://qiita.com/advent-calendar/2022/qiita-inc)の9日目は、
Qiita 株式会社 プロダクト開発G デザインTMの出口（@degudegu2510）が担当します！

普段の業務は、Qiita, Qiita Team, Qiita Jobsのデザイナーとして、情報設計、体験設計(UX)、UIデザイン、フロントエンドまで携わっています。

この記事では、Qiitaで使っているCSS in JS の👩‍🎤Emotionについて
👩‍🎤Emotionの特徴やQiitaで👩‍🎤Emotionを使っている理由などをまとめました。

CSS in JSは、何がいいんだろうと考えている人や👩‍🎤Emotionを導入しようと検討している人などの参考になれば幸いです。

## 👩‍🎤Emotion
### 👩‍🎤Emotionとは？
<!-- 20秒 -->
![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/6488caef-eadd-7ad8-16be-993101a49bc8.png)
[💅 styled-components](https://styled-components.com/)・[💄glamorous](https://glamorous.rocks/) といったCSS-in-JSライブラリにインスパイアされた比較的後発のライブラリです。そのため、非常に多機能であり、他ライブラリの機能の多くを更に洗練させた上で備えているのが特徴です。

また、ReactやVueといったフレームワークに依存することなく、CSS in JSを利用することができるため汎用性が高く、[💅 styled-components](https://styled-components.com/) よりもパフォーマンスが高いのも特徴になります。

### 主な機能の紹介
#### ① CSS Props と Styled Components
👩‍🎤Emotionが比較的後発のライブラリであるため、他のCSS in JSからインスパイアされ、多くの書き方ができます。
![image2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/18fbd7b6-40f6-6a49-fb5b-0e0493f06255.png)
**CSS Props**では、`css={paragraph}` のように、class名をしているようにでき、DOM構造とスタイルを分けて記述できるのも特徴です。

また、*オブジェクト記法*と*タグ付きテンプレートリテラル記法*の2つの書き方ができます。

*オブジェクト記法*は、厳密な型定義がされるため予測変換しやすいですが、CSSのプロパティがキャメルケースになります。

*タグ付きテンプレートリテラル記法*は、cssのプロパティをそのまま記載できますが、ストリングのためエラー検知しづらいです。 *※プラグインを入れればなんとかなる*

![image3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/347f7020-baca-c030-51a3-359d15dcd121.png)
**Styled Components**では、`styled.p…`　のようにDOM要素の宣言は、スタイルと一緒に記載するのが特徴です。

また、Styled Componentsでも*オブジェクト記法*と*タグ付きテンプレートリテラル記法*の2つの書き方ができます。

*オブジェクト記法*は、厳密な型定義がされるため予測変換しやすいですが、CSSのプロパティがキャメルケースになります。

*タグ付きテンプレートリテラル記法*は、cssのプロパティをそのまま記載できますが、ストリングのためエラー検知しづらいです。 *※プラグインを入れればなんとかなる*


#### ② @emotion/css
👩‍🎤Emotionは、Reactやvue.js、などのJavascriptのライブラリーに左右されないようにするためのパッケージが用意されています。

それが`@emotion/css`になります。

ただ、Reactで最適に使いたい場合や、Styled Componentsを使いたい場合は、以下のように別のパッケージが用意されています。

+ `@emotion/react`
    + React用のEmotionパッケージ
+ `@emotion/styled`
    + Styled Components用のEmotionパッケージ
+ `@emotion/css`
    + フレームワークにとらわれず、Emotionを使用するためのパッケージ


## 👩‍🎤Emotionを使っている理由
### セマンティックなマークアップを実現したかった。
<!-- 90秒 -->
👩‍🎤Emotionを使っている理由の1つ目は、Emotionは楽にセマンティックなマークアップを実現できることです。

[💅styled-components](https://styled-components.com/)を使っていた中で課題になったのは、セマンティックなマークアップの実現がやりにくいことです。SEOやアクセシビリティを向上させるためにも、セマンティックなマークアップは必要です。

そこで、`💅styled-components`と`👩‍🎤Emotion`の違いを見ていきましょう。
![image4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/7255f264-7988-5e1a-1391-3fb0855f8c31.png)

`💅styled-components`は、要素の宣言をスタイル側に持たせています。
そのため `<Paragraph>` のタグを見るためには、`<Paragraph>`で参照している行まで行く必要があります。

`<Paragraph>`といったタグを連想しやすい名前をつけていればいいのですが、そんなことは、なくこんな感じのコードが生まれます。
![image5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/71754c80-a07a-f771-8515-867f58d49a2f.png)
`<a>` なのに `<SampleButton>`が使われたり、`<list>`なのに、`<div>`が使われたりなど、命名規則などで縛っても難しい部分もあり、セマンティックのマークアップが難しいです。

それに比べてEmotionは、マークアップとスタイルを分けて記述できるという点が、
CSS in JSにEmotionを選んでいる１つ目の理由です。


### Emotoinへの移行がやりやすかった。
<!-- 90秒 -->
Qiitaは今年で11年目のプロダクトになり、多くのコンポーネントが作られています。
それらのコンポーネントたちを一斉に変更するだけでも一苦労です。 

そのため、ライブラリーの変更がしやすいこともEmotionを選んでいる理由の１つです。

具体的には、以下のようにEmotionを変更していきました。

`💅styled-components` → `👩‍🎤@emotion/styled` → `👩‍🎤@emotion/css`

まずは、`💅styled-components` から `👩‍🎤@emotion/styled` に変更します。
スタイリングの部分に関しては、以下のように基本的に変わりません。
そのため、`💅styled-components` から `👩‍🎤Emotion`への変換はそこまで大変ではありませんでした。
![image6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/c98135fe-4e87-0256-0a8f-7c283b66f506.png)

`👩‍🎤@emotion/styled`に変えたら、他のPJを進めなから、順次`@emotion/css`にリファクタリングしていきます。

このように、スムーズに `👩‍🎤Emotion` への移行することができる点が
CSS in JSにEmotionを選んでいる２つ目の理由です。

## 4. まとめ
<!-- 30秒 -->
この記事では、Qiitaで使っているCSS in JS のEmotionについて
Emotionの特徴やQiitaでEmotionを使っている理由などをまとめました。

Emotionは、💅 styled-components よりもパフォーマンスが高く、セマンティックなマークアップが実現でき、
移行するのもスムーズです。

ただ、近年台頭してきているゼロランタイムのCSS in JSの方が、パフォーマンスがいいらしいので、
ゼロランタイムのCSS in JSに移行するのも近いかもしれません。

ゼロランタイムのCSS in JSに移行した際は、また記事にまとめようと思いますのでお楽しみしてください。

---

最後まで読んでくださってありがとうございます！

普段はデザインやフロントエンドを中心にQiitaに記事を投稿しているので、ぜひQiitaのフォローとX(Twitter)のフォローをお願いします。

https://twitter.com/degudegu2510