Vite+React+TypeScriptで、CSSスタイルについて調べて、Emotionに流れ着いた
React調べること多すぎ・・・🤯
今回はReactのCSSスタイルついて調べてみました。
まとめ
いきなりまとめです。
ReactのCSSスタイルについての結論
- これといった正解はない。
- 将来どうなるかはわからない。
- 今のメンバのスキルセットで、使いたいものを使えばいいんじゃないだろうか?
ということで、React(Vite + TypeScript)のCSSスタイルについて調べて、Emotionに流れ着いた経緯と、Emotionの導入方法についての記事です。
主要なもの
2022年2月24日時点で、ザクっと調べた主要なものです。
マイナーなものを含めるともっとありますが、今回は主要な以下の8つから選択します。
- Inline Styles
- Css Modules
- Styled JSX
- Styled Components
- Emotion
- Linaria
- Tailwind CSS
- Windi CSS
1. Inline Styles
Style属性に直接スタイルを指定します。
Css in JS (JavaScriptのコード中にCSSを書く手法)です。
開発時にちょこっと使うのに使用するようです。
サンプル
export function InlineStyle() {
return (
<div style={{ width: "100%", padding: "20px", backgroundColor:"#CE6270"}}>
<p style={{ color: "#FBBDAE", textAlign: "center" }}>Inline Style</p>
</div>
)
}
事前定義してスタイルに適用することもできます。
const divStyle = {
width: "100%",
padding: "20px",
backgroundColor:"#CE6270"
}
const textStyle = {
color: "#FBBDAE",
textAlign: "center"
}
export function InlineStyle() {
return (
<div style={divStyle}>
<p style={textStyle}>Inline Style</p>
</div>
)
}
2. Css Modules
コンポーネントファイルとは別にcssファイルを用意し、従来のCSSの書き方で記述します。
Viteで標準サポートされています。
コンポーネントファイルとCSSファイルを分けるのでファイル数が増え見通しが悪くなります。
サンプル
import styles from './CssModule.module.css';
export function CssModule() {
return (
<div className={styles.divstyle}>
<p className={styles.textstyle}>CssModule</p>
</div>
)
}
「コンポーネント名.module.css」という名前でファイルを作る。
.divstyle {
width: 100%;
padding: 20px;
background-color: #CE6270;
}
.textstyle {
color: #FBBDAE;
text-align: center;
}
3. Styled JSX
コンポーネントファイルにcssを文字列で定義します。
従来のcssの書き方ができます。
Next.jsで標準サポートされています。
Vite+React+typescript環境で試したところ、TypeScriptコンパイラエラーと実行時に警告が発生しました。
サンプル
npm install styled-jsx --save-dev
export function StyledJsx() {
return (
<>
<div className="divstyle">
<p className="textstyle">StyledJsx</p>
</div>
<style jsx>{`
.divstyle {
width: 100%;
padding: 20px;
background-color: #CE6270;
}
.textstyle {
color: #FBBDAE;
text-align: center;
}
`}</style>
</>
)
}
スタイルを事前定義することも可能です。
ただし、グローバルスタイルとスコープ付きスタイルを生成するそうです。
コチラのパターンはVite+React+typescript環境でエラーが発生し実行できませんでした。
import css from 'styled-jsx/css'
export function StyledJsx() {
const styles = css`
divStyle {
width: '100%',
padding: '20px',
background-color: '#CE6270'
}
textstyle = {
color: '#FBBDAE',
text-align: 'center'
}
`
return (
<>
<div className="divstyle">
<p className="textstyle">StyledJsx2</p>
</div>
<style jsx>{styles}</style>
</>
)
}
4. Styled Components
スタイルを当てたコンポーネントを定義します。
CSSを設定する要素ごとにコンポーネントを作ることになるため、HTMLとしての可読性が低くなります。
サンプル
npm install styled-components
npm install @types/styled-components --save-dev
import styled from 'styled-components'
export function StyledComponents() {
return (
<>
<StyledDiv>
<StyledP>StyledComponents</StyledP>
</StyledDiv>
</>
)
}
const StyledDiv = styled.div`
width: 100%;
padding: 20px;
background-color: #CE6270;
`
const StyledP = styled.p`
color: #FBBDAE;
text-align: center;
`
5. Emotion
Inline Styles、Styled JSX、Styled Componentsと同様の書き方ができます。
6. Linaria
Css in Js。
Cssはビルド時にCSSファイルに抽出される、ゼロランタイム。
Viteに導入するのは時期尚早のよう。
7. Tailwind CSS
Tailwind v2.0と完全互換なWindi Cssがあります。
そちらの方がビルド時間が速いので、導入するならWindi CSSがよいのではと思います。
8. Windi CSS
Viteに対応しています。
Bootstrapみたいな書き方をします。
サンプル
<p className="text-gray-500 font-medium">Product Engineer</p>
選択肢を絞るまでの経緯
1. Inline Style
開発用にちょこっと使用するものなので選択肢から外します。
2. Css Modules
Vite標準なので、導入コストがないのは有難いです。
試してみたのですが、やはりファイルが分かれることがネックです。
コンポーネントを分けようと思うときに躊躇してしまいます。
今回は選択肢から外しました。
3. Styled JSX
Viteで使用するのにコンパイルエラーや実行時の警告を解消する調査が手間なので、選択肢から外します。
4. Styled Components
試してみたのですが、やはり可読性が悪いと感じました。
スタイルを付けたコンポーネントは、ネーミングを工夫して「Styled●●●●●Div」とか「Styled●●●●●P」とかしてみたのですが、HTMLの構造がパッとみて掴みづらかったです。
今回は選択肢から外しました。
5. Emotion
最終的に選択肢に残りました。
Emotion で Styled JSX のような書き方を使用したいと思います。
6. Linaria
Viteに導入するのは時期尚早のようなので、選択肢から外します。
7. Tailwind CSS
導入するならWindi Cssなので選択肢から外します。
8. Windi CSS
個人的な好みの問題で、選択肢から外します。
HTMLはできる限りスッキリさせときたい派でCSSは分離させたいです。
あとは CSS と WindiCSSのクラス との変換が面倒です。
Emotionを導入する
Emotionは Inline Styles、Styled JSX、Styled Componentsと同様の書き方ができます。
今回は Styled JSX のような書き方で Object Style を使用したいと思います。
インストール
@emotion/react をインストールします。
(@emotion/babel-plugin は必要ありません)
※ styled component のような書き方をする場合は「@emotion/styled」のインストールが必要です。
npm install @emotion/react
設定
各tsxファイルにプラグマ [import jsx from '@emotion/react'] の記述がないと、コンパイルエラーになるため、tsconfig.jsonに記述します。
"compilerOptions": {
・・・中略・・・
"jsxImportSource": "@emotion/react",
vite.config.tsは、tsconfig.json の jsxImportSource を参照しないので、こちらにも追記します。
plugins: [react({
jsxImportSource: '@emotion/react',
})]
サンプル
Inline Style の書き方
Emotion の Inline Styleは、Css in Js の書き方で記述します。
<div css={{ color: 'red' }}>Inline Style</div>
Styled JSX のような書き方 (String Style)
Emotion の String Styleは、 従来の css の書き方で記述します。
import { css } from '@emotion/react'
const styles = {
divstyle: css`
width: 100%;
padding: 20px;
background-color: #CE6270;
`,
textstyle: css`
color: #FBBDAE;
text-align: center;
`
}
export function EmotionStringStyle() {
return (
<div css={styles.divstyle}>
<p css={styles.textstyle}>Emotion String Style</p>
</div>
)
}
String Styleを使用する際は、VsCode 拡張機能 vscode-styled-components
を使用すると、インテリセンスとシンタックスハイライトが効くようになります。
Styled JSX のような書き方 (Object Style)
Emotion の Object Styleは、 Css in Js の書き方で記述します。
import { css } from '@emotion/react'
const styles = {
divstyle: css({
width: '100%',
padding: '20px',
backgroundColor: '#234867'
}),
textstyle: css({
color: '#30A6BC',
textAlign: 'center'
})
}
export function EmotionObjectStyle() {
return (
<div css={styles.divstyle}>
<p css={styles.textstyle}>Emotion Objectg Style</p>
</div>
)
}
以上
React(Vite + TypeScript)のCSSスタイルについて調べて、Emotionに流れ着いた経緯と、Emotionの導入方法についてでした。
技術選定の際に参考にしたサイト
Discussion