ReactのCSS記述方法は戦国時代らしい。しっかり学習しておく必要がある。
Pure CSS
通常のCSSです。create-react-appした時にデフォルトで適用されているCSSでもあります。
メリット
「通常のCSS」なので学習コストが低いことでしょう。
デメリット
保守性が低い
- CSSが全てグローバルで管理されてしまうので保守、運用、管理にコストがかかる。BEMなどでスコープを作って対策するケースが多いです。
- BEMなどで対策した場合は、命名が非常に長くなってしまう。対策法としては、SassなどのCSSプリプロセッサで簡略化する。
- ただ、Sassなどで対策した場合はコードの検索ができない。
Inline Styles
サンプル
1 2 3 4 5 6 7 8 9 |
const containerStyle = { border: "solid #000 1px ", borderRadius: "10px", }; return ( <div style={containerStyle}> <InlineStyle /> </div> ); |
普通のJSのようにソースを記述ができます。普通のCSSと異なりプロパティ名はスネークケースではなく、キャメルケースで記述します。
CSS Modules(Css Loader)
WebpackのローダーでCSSのクラスをJSで読み込む方法
メリット
- Css LoaderによってCSSにスコープという概念を作れる。インポートしたコンポーネントにしか影響しないので競合がなく安心
- 記述はPure CSSに近いので学習コストは低め。
- 既存のリンターが使える。
デメリット
- コンポーネントを跨ぐCSS共通化は難しい。(Sassである程度解消できる。)
- 将来非推奨になる可能性がある。
- ファイルが増える。(CSS in JSと比較すると。CSS in JSなら1ファイル)
サンプル
{コンポーネント名}.module.scss
1 2 3 4 |
.container { border: solid #000 1px; border-radius: 10px; } |
コンポーネント名と同じ名前がついたcss(もしくはscssなど)に普通のCSSを記述します。
{コンポーネント名}.jsx
1 2 3 4 5 6 |
import classes from "./CssModules.module.scss"; <div className={classes.container}> <p>- CssModules -</p> <button>- CssModules -</button> </div> |
className属性を使って上記のようにclass指定します。
styled-jsx
インストール(Next.jsなら不要)
1 |
npm install styled-jsx |
なお、Next.jsにはデフォルトで入っているのでもしNext.jsを使っている案件であればインストールは不要です。
サンプル
1 2 3 4 5 6 7 8 9 10 |
<div className="container"> <p>- Styled -</p> <button>- Styled -</button> </div> <style jsx="true">{` .container { border: solid #000 1px; border-radius: 10px; } `}</style> |
注意点
デフォルトではhoverなどの疑似要素は使えない。sass記法などが使えるプラグインもあるみたい。
CSS in JS
CSSをJSで記述しましょうという方法、コンポーネントごとに「コンポーネント名.modules.css」というファイルを作りスコープを作れる。
メリット
- propsとしてデータを渡せるので動的にスタイル変更ができる。
- コンポーネント単位でスコープを作れる。
- JSファイルに全て記述するので可読性は優れる。
デメリット
- CSS-modulesとかに比べてレンダリング速度は劣る。(CSS-modulesはビルド後は生CSSのため):Linariaを使えば懸念は解消できる。
- 通常のpropsとスタイルのpropsが混在してしまう。
- ぱっと見なんのタグかわからない。
- 従来のlinterは使えない。(TSである程度カバーはできる。)
代表格
CSS in JSで人気のある手法です。
Styled Components
根強い人気があって今でも人気上位のReact CSSライブラリになります。
メリット
sassと同じ記法で記述ができ、hoverなどが使える。(普通のcssがデフォルトで拡張されている。)、なのでsassからReactに置き換える際などの移行にも便利だったりします。
デメリット
スタイルを当てたコンポーネントなのか、importしたコンポーネントなのかがぱっと見で非常にわかりづらいです。なので人によってはスタイルを当てたコンポーネントに関してはコンポーネント名の先頭に「S」をつけるなどしてぱっと見わかるようにしていたりもします。
インストール
1 |
npm install styled-components |
サンプル
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import styled from "styled-components"; function StyledComponents() { return ( <> <Cotainer> <p>- StyledComponents -</p> <button>- StyledComponents -</button> </Cotainer> </> ); } const Cotainer = styled.div` border: solid #000 1px; border-radius: 10px; `; |
スタイルの共通化(というか継承)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
function StyledComponents() { return ( <> <MainCotainer> <p>- StyledComponents -</p> <button>- StyledComponents -</button> </MainCotainer> </> ); } const BaseCotainer = styled.div` border: solid #000 1px; border-radius: 10px; `; const MainCotainer = styled(BaseCotainer)` background-color: #555; `; |
「styled(継承元スタイル)」という感じで新しいスタイルを定義することでスタイルを継承して別スタイルとして定義することも可能です。
ユースケース
ほぼ同じようなボタンだけど背景色だけ変えたいみたいな要求があったとした場合に共通化するために使ったりします。
デメリット
- 通常のタグと「Styled Components」の区別が付かない。(Emotionならこのデメリットはない。)
Emotion
Styled Componentsよりも後発になります。2018年8月に出てから急速に伸びて1年後にStyled Componentsを抜いている。
後発なだけあってStyled Componentsよりも痒い所に手が届いています。「タグ付きテンプレート文字列による記述」と「オブジェクト記法」の二つがサポートされています。
v11からは、TSをサポートしたことでjsxの型を上書きする必要があります。
Linaria
クライアント側で負荷がかからない。記述方法は「styled-components」とほぼ同じ。IE11が非対応。
インストール
1 |
npm i @emotion/styled @emotion/react |
サンプル1(Sassと同じ記法)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import { css } from "@emotion/css"; function Emotion() { const containerCss = css` border: solid #000 1px; border-radius: 10px; `; return ( <> <div css={containerCss}> <p>- Emotion -</p> <button>- Emotion -</button> </div> </> ); } |
この手法であれば、sassと同じ書き方ができます。
サンプル2(inline-styleと同じ記法)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import { css } from "@emotion/css"; function Emotion() { const containerCss = css({ border: "solid #000 1px", borderRadius: "10px", }); return ( <> <div css={containerCss}> <p>- Emotion -</p> <button>- Emotion -</button> </div> </> ); } |
サンプル3(styled-componentsと同じ記法)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import styled from "@emotion/styled"; function Emotion() { return ( <> <Cotainer> <p>- Emotion -</p> <button>- Emotion -</button> </Cotainer> </> ); } const Cotainer = styled.div` border: solid #000 1px; border-radius: 10px; `; export default Emotion; |
CSS Framework
Tailwind
classNameに適用したいクラスを追加していく。CSS in JSライブラリとも組み合わせられる。
メリット
すでにクラスが用意されているので実装が早い。
デメリット
CSSの当て方がTailwind独特のものなので学習コストが高い。
この記事へのコメントはありません。