【React.js】CSS-in-JSを使ったスタイリング(styled-componentsとEmotion)
目次
今回はReact.jsにおいてHTML要素にCSSスタイルを当てる方法をご紹介します。
React.jsでは数多くのスタイリング手法がありますが、今回はよく使われているとされているCSS-in-JS、その中でも多く使われているstyled-componentsとEmotionについてまとめます。
今まで投稿したReact.jsに関する記事は下記になりますので、是非こちらも合わせてご覧ください。
【React.js】React.jsとは?環境構築やHello World表示までをご紹介
https://www.dailyupblog.com/web_development/1830/
【React.js】React.jsにおけるコンポーネントとpropsの使い方をご紹介!
https://www.dailyupblog.com/web_development/1860/
【React.js】useStateとuseEffectの使い方をご紹介(React hooksを学ぶ)
https://www.dailyupblog.com/web_development/1888/
【React.js】React Routerで画面遷移をしてみよう
https://dailyupblog.com/web_development/2042/
ReactにおけるCSS
ReactにおけるCSSスタイルの手法は多岐にわたります。
Vue.jsのようにフレームワークで決まったスタイルのルールがあるわけではないです。
やり方は様々で、書きやすさやプロジェクト全体での管理のしやすさなどで、選ぶのが良いかもしれません。
グローバルCSS
まず、グローバルCSSです。
これは単純に、グローバルなCSSファイルを作成して、各コンポーネント内でこのファイルをインポートして使うパターンです。
「src」ディレクトリ直下に「style」ディレクトリを作成し、その中にglobal.cssを作成してそれを読み込ませます。
h1 {
color: #f00;
}
import "../style/global.css";
const Hello = () => {
return (
<>
<h1>Hello World</h1>
</>
);
};
export default Hello;
これは、正直コンポーネント志向の開発にはあまり向きません。
クラスの衝突を避けなければなりませんし、クラスの使い回しではなくコンポーネントの使い回しという考え方には反します。
またコンポーネントごとにCSSを読み込ませる方がレンダリングの時間も短縮できて、ユーザビリティ的にも良いです。
インラインスタイル
インラインスタイルは、グローバルスタイルよりは、コンポーネント志向の書き方といえるでしょう。
タグのstyle属性にキャメルケースでスタイルを書きます。
const Hello = () => {
return (
<>
<h1 style={{ color: "red", fontSize: "40px" }}>Hello World</h1>
</>
);
};
export default Hello;
CSSのプロパティはキャメルケースで書く必要がありますが、ケバブケースで書くことも可能で、その場合はプロパティの部分をダブルクォーテーションで囲う必要があります。
インラインスタイルの欠点としては、同じスタイルを指定したい場合は同じスタイルを属性で指定する必要があったり、擬似要素やメディアクエリが使えなかったり、読み込みのたびにスタイルの計算が走るためパフォーマンスも良くありません。
なので、実用的ではありませんが、開発中にちょっとスタイルを当てたい時や、動的計算が必要となるスタイルの時などに限定して使うようにしましょう。
CSS Modules
CSS Modulesは上に紹介した二つよりももう少し使い勝手のいいものです。
CSS Modulesは、コンポーネント単位でスタイルを当てることが可能であり、クラスの衝突も起こりません。
まさにReact.jsに向いていると言えます。
使い方は下記です。
.black_btn {
background: #000;
color: #fff;
border: 1px solid #000;
}
import button from "../style/button.module.css";
const Button = () => {
return <button className={button.black_btn}>こちらをクリック</button>;
};
export default Button;
「style」ディレクトリ内に作成した「button.module.css」ファイルをコンポーネント内で読み込ませて、使っていjます。
CSS Modulesでは、「*.module.css」というファイル名にするというルールがあります。
先述の通りコンポーネント単位での使用に向いているし、利用者も多いですが、今後廃止される可能性が高いとされています。
なので、筆者は次に紹介するCSS-in-JSを利用することにしました。
CSS-in-JS
CSS-in-JSとは、その名の通り、CSSをJavaScriptで記述しようというものです。
CSS-in-JSは、コンポーネントファイル内に記述するので、コンポーネント志向の開発に向いています。
また、メディアクエリや擬似要素・擬似クラスの記述にも対応しており、propsによる動的なスタイルの変更なども可能です。
利用者も多く、Reactにおいて、万能な記法といえます。
今回は、CSS-in-JSの中でも、利用者の多いstyled-componentsとEmotionの二つを紹介します。
styled-components
styled-componentsを利用するには、コマンドでパッケージをインストールします。
//npmの場合
npm install styled-components
npm install @types/styled-components
//yarnの場合
yarn add styled-components
yarn add @types/styled-components
※@types/styled-componentsは、typescriptを使用している場合に必要です。
import styled from "styled-components";
const Hello = () => {
const Title = styled.h1`
font-size: 40px;
color: #f00;
`;
return (
<>
<Title>Hello World</Title>
</>
);
};
export default Hello;
styled-componentsでは、上記のようにJavaScriptでCSSスタイルを表現しています。
そして、HTML上でスタイルを当てるには、定義したスタイル(上記の例だと、「Title」)を<Title>というタグとして使うことで、指定したスタイルが適用されます。
下記は、styled-componentsでメディアクエリや擬似要素・擬似クラスの書き方です。
import styled from "styled-components";
const Hello = () => {
const Title = styled.h1`
font-size: 40px;
color: #f00;
span {
display: block;
color: #000;
font-size: 18px;
}
@media screen and (max-width: 767px) {
font-size: 24px;
}
&:before {
content: "★";
}
`;
return (
<>
<Title>
Hello World<span>Good Morning</span>
</Title>
</>
);
};
export default Hello;
styled-componentsでは、scssのようにCSSを入れ子で記述することができます。
なので、入れ子でメディアクエリや擬似要素を書きましょう。
また、入れ子で書くことができるため、上記のようにh1中のspanタグに対して、入れ子でスタイルを記述することも可能というわけです。
Emotion
Emotionもstyled-componentsと書き方は似ています。
ただ、書き方が一部異なります。
Emotionも同じように、コマンドでパッケージをインストールしましょう。
//npmの場合
npm install @emotion/react @emotion/babel-plugin
//yarnの場合
yarn add @emotion/react @emotion/babel-plugin
/** @jsxImportSource @emotion/react */
import { css } from "@emotion/react";
const Hello = () => {
const Title = css`
font-size: 40px;
color: #f00;
span {
display: block;
color: #000;
font-size: 18px;
}
@media screen and (max-width: 767px) {
font-size: 24px;
}
&:before {
content: "★";
}
`;
return (
<>
<h1 css={Title}>
Hello World<span>Good Morning</span>
</h1>
</>
);
};
export default Hello;
※Emotionのインポートの記述の上に「/** @jsxImportSource @emotion/react */」を記述しないと、Emotionが使えない場合があるようですので、念の為記述しておきましょう。
先ほどのstyled-componentsの例をEmotionで書いてみました。
書き方はほぼ同じですが、styled-componentsとの違いは、定義したスタイルを当てるときに、タグで指定しているのではなくて、スタイルを当てたいタグに対して、css属性に定義したスタイルを指定することです。
また、一つのタグに複数のスタイルを指定することができます。
その場合は、css属性内に配列で記述しましょう。
<h1 css={[Title, ColorBlue]}>
Hello World<span>Good Morning</span>
</h1>
最後に
今回は、ReactにおけるCSSの書き方について紹介いたしました。
Reactには、決まったCSSの書き方がないので、正解がありません。
自分やプロジェクトチームにあった書き方で書くのがいいと思います。
筆者はstyled-componentsが一番管理しやすく、コンポーネント指向の開発に向いていると思ったので、styled-componentsを使っていこうと思います。