当サイトは、アフィリエイト広告を利用しています

Emotionの使い方

作成日:2022月01月19日
更新日:2024年02月06日

当ブログを作成するにあたりCSS in JSのEmotionを使ったので
基本的な使い方を忘備録として残す。
またブログの実装で使ったサンプルもまとめておく。

TypeScriptで使う場合については下記記事にてまとめています。

ReactでのEmotionの基本の書き方

Emotionには大きく

  • ストリングスタイル
  • オブジェクトスタイル
  • styled-component

の三つがある。

StringStyles

バッククォートを使った一番基本的な書き方。
私もこの書き方で実装しています

StringStyles
import { css } from '@emotion/react'
const bgcolor = "#666666";
const Box1 = css`
width: 200px;
height: 100px;
background-color: ${bgcolor};
color: white;
`
<div css={Box1}>box1</div>

CSSと同じ様にコードを書くことができるので
馴染みやすいと思います。

ObjectStyle

オブジェクトスタイルで書く。 オブジェクトスタイルで書く場合、下記のような注意点がある

  • プロパティはキャメルケースで書く
  • 値は文字列
  • プロパティを複数設定する際は、セミコロンではなくカンマで区切る
ObjectStyle
import { css } from '@emotion/react'
const bgcolor = "#666666";
const Box2 = css({
width: "200px",
height: "100px",
backgroundColor: "green",
color: "white",
})
<div css={Box2}>box2</div>

styled-component

styed-component っぽく書くこともできる
typescriptで書く場合は恩恵がうけられる

【パターン1】

styled.div の形で書く

styled-component_1
import styled from '@emotion/styled'
const bgcolor = "#666666";
const Box3 = styled.div`
width: 200px;
height: 100px;
background-color: ${bgcolor};
color: white;
`
<Box3>box3</Box3>

【パターン 2】

ObjectStyle の形で書く

component_2
import styled from '@emotion/styled'
const bgcolor = "#666666";
const Box4 = styled.div({
width: "200px",
height: "100px",
backgroundColor: "#663399",
color: "white",
})
<Box4>box4</Box4>

Emotionの使い方のサンプル

EmotionはCSSinJSのため関数にして引数を渡すこともできる
StringStylesで定義したCSSを返却する関数を作り、csspropsを使って
スタイリングするサンプルをまとめる。

csspropsで関数を使う

CSSの値を動的に記述したい場合はCSS(StringStyles)を返却する関数を
作り、引数を渡すことで実現できる。
css={}の中身は配列でも変数でも設定可能。
※だが配列でないとエラーになるパターンもあるため
基本的には配列の形にしておく。

jsx
//関数にする
const buttonStyle = (backgroundColor) =>[
css`
outline: none;
border: none;
display: block;
box-sizing: border-box;
padding: 16px 32px;
font-size: 0.75rem;
font-weight: 600;
box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 4px inset;
text-align: center;
background-color: ${backgroundColor};
`];
const Button = ({ backgroundColor }) => (
// 呼び出し時に引数を渡す
<button css={[buttonStyle(backgroundColor)]} />
);

実装サンプル

下記に実装サンプルをのせます!

Emotion_cssprops_useFunction1

csspropsで関数を使う(関数の中で関数を使う)

EmotionはCss in JSなので関数を扱うことができる。
そのため、関数の中で別の関数を定義して使うこともできる

関数の中で関数を使う
const buttonStyle = (flg) => {
// 関数を作る
const changeColor = (flg) => {
if (flg) {
return "blue";
} else {
return "red";
}
};
return [
css`
outline: none;
border: none;
display: block;
box-sizing: border-box;
padding: 16px 32px;
font-size: 0.75rem;
font-weight: 600;
box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 4px inset;
text-align: center;
/* 作成した関数を設定できる */
background-color: ${changeColor(flg)};
`
];
};
const Button = ({ flg }) => (
// 呼び出し時に引数((true or false))を渡す
<button css={[buttonStyle(flg)]}>ボタン</button>
);
  • EmotionのStringStylesはCSS文字列を返却する関数だと考えた方が理解しやすい

実装サンプル

下記に実装サンプルを載せます

Emotion_cssprops_useFunction2

csspropsで関数を使う(関数の中で三項演算子を使う)

CSSpropsの${}の中で三項演算子を使うこともできる

関数の中で三項演算子
//関数にする
const buttonStyle = (flg) => {
return [
css`
outline: none;
border: none;
display: block;
box-sizing: border-box;
padding: 16px 32px;
font-size: 0.75rem;
font-weight: 600;
box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 4px inset;
text-align: center;
/* 三項演算子を設定 */
background-color: ${flg?"red":"blue"};
`
];
};
const Button = ({ flg }) => (
// 呼び出し時に引数((true or false))を渡す
<button css={[buttonStyle(flg)]}>ボタン</button>
);

実装サンプル

下記に実装サンプルをのせます

Emotion_cssprops_useFunction3

csspropsで関数を使う(条件で返却するCSSを分岐させる)

条件のよって返却するcssを変更する関数も定義できる。

return_css
const hoge2 = flg => {
if (flg) {
return css`
background-color: red;
`;
}
return [
css`
background-color: blue;
`,
];
};
const sample = ()=>{
return (
<div id="toggle" css={[hoge2(false)]}>
Toggle Me!
</div>
)
}
  • EmotionのStringStylesはCSS文字列を返却する関数~

実装サンプル

下記に実装サンプルをのせます

Emotion_cssprops_returnCss

csspropsで関数を条件付きで実行する。

csspropsで設定したCSS(StringStyles)を返却する関数を

  • ショートサーキット評価
  • 三項演算子

で判定してから実行させることもできる。
ショートサーキット評価については下記記事でまとめています。

cssprops_inlineConditional
/** @jsxImportSource @emotion/react */
import { css } from "@emotion/react";
import { useState } from "react";
// インラインで関数を条件付きで実行する場合
export default function App() {
const [state, setState] = useState(false);
const Button = () => {
return <button onClick={() => setState((prev) => !prev)}>色変更</button>;
};
return (
<div className="App">
<div
css={[
css`
display: grid;
justify-content: center;
`
]}
>
<h1>インラインで関数を条件付きで実行する</h1>
<Button />
<h1
css={[
// ショートサーキット評価で判定
state && buttonStyle,
// 三項演算子で判定
// state ? buttonStyle:""
css`
text-align: center;
`
]}
>
Hello Emotion
</h1>
</div>
</div>
);
}
const buttonStyle = () => {
return [
css`
background-color: skyblue;
`
];
};
  • ボタン押下時にstateを更新し、その値によってCSS(StringStyles)を付け替える。
  • 判定処理はショートサーキット評価で行える。※三項演算子でもできる

実装サンプル

下記に実装サンプルをのせます

Emotion cssprops_inlineConditional

StringStylesをインラインで指定する

上記の「StringStylesで関数を使う」では外でStringStylesで関数を定義して
propsで渡していたが、jsx内にインラインで書くこともできる。

書き方としては

js
css={[css`xxxxx`]}

のように配列の形で受け取る必要がある。

StringStyles_inline
<div
css={[
css`
display: grid;
grid-template-columns: 300px;
justify-content: center;
background-color: yellow;
`
]}
>
<h1>Emotion Sample</h1>
</div>
  • []をとるとエラーになる
  • 大量に書くと可読性が下がるので注意!

実装サンプル

下記に実装サンプルをのせます

Emotion_cssprops_inline

StringStylesをインラインで複数指定する

Emotionで定義したcssを複数指定することもできる。
ただ呼び出し側は配列の形で受け取る必要がある。 直書きと一緒に書くこともできる。

jsx
// emotionでcssを定義
const borderBase = css`
border: 1px solid gray;
border-radius: 5px;
`
// emotionでcssを定義
const iconButton = css`
border-radius: 50%;
`
// 配列で設定する
<button css={[borderBase, iconButton]}>?</button>
// 直書きと一緒に書くこともできる
<button css={[borderBase, css`background-color: red;`]}>?</button>

実装サンプル

下記に実装サンプルを載せます

Emotion_cssprops_inline_multiple

インラインで関数を定義する

props内でインラインで関数を書いて使うこともできる
下記のような形になる。

inline_function
<h1
css={[
() => [
css`
color: ${flg ? "red" : "blue"};
`
]
]}
>
hello Emotion
</h1>
  • 正直、見づらいので外で定義したほうがいい...

一応、サンプル載せときます

Emotion_cssprops_inlineFunctiion

実際に使ってみて

emotionについては色々な書き方ができるので自分の中で書き方を統一しておいた方が良いです。
下記にサンプルルールを書きます。

emotionでcssを定義する側のルール

  • 関数の形で書く
  • 戻り値は配列にする。
jsx
const container = ()=>[
css`
height: 100%;
background-color: white;
color: red;
`,
];

基本的に関数の形で戻り値は配列で書いた方いい。引数を追加する場合や
他のcssを取り込む場合などに柔軟に対応できるため。

emotionで定義したcssを読み込む側のルール

  • 呼び出す側も配列で受け取るようにする。
jsx
// 呼び出す側も配列で書く
<div css={[container]}>
<p>
current color mode:
{colorMode}
</p>
<button onClick={setColorMode}>toggle color mode</button>
</div>

配列の形で受け取るようにする。色々追加や変更する場合も
配列にしていた方が対応しやすいため。

オブジェクトの形にまとめる

同じ分類のcssをオブジェクトの形にまとめるようにする。
emotionはCSS in JSなのでjavascriptの書き方で管理できる

jsx
/** @jsxImportSource @emotion/react */
import { css } from "@emotion/react";
export default function App() {
// オブジェクトにまとめる
const styles = {
// 関数を設定
styleA: (coler) => [
css`
text-align: center;
width: 300px;
background-color: ${coler};
`
],
// 値を設定
styleB: [
css`
text-align: center;
width: 300px;
color: blue;
`
],
// 疑似クラスを設定
styleC: [css`
&:hover {
background-color: rgba(0, 0, 255, 0.5);
}
`]
}
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<div
css={[
css`
display: flex;
justify-content: flex-start;
`
]}
>
<div css={[styles.styleA("green")]}>styleAのみ適用</div>
<div css={[styles.styleB]}>styleBのみ適用</div>
</div>
{/* まとめて適用する */}
<div css={[styles.styleA("green"), styles.styleB,styles.styleC]}>
styleA,styleB,styleCの適用
</div>
</div>
);
}

styleB,styleCはサンプルの意味で敢えて関数の形で書いていないが
関数の形で書くこともできる。

jsx
// 値を設定
styleB: () => [
css`
text-align: center;
width: 300px;
color: blue;
`
],
// 疑似クラスを設定
styleC: () => [
css`
&:hover {
background-color: rgba(0, 0, 255, 0.5);
}
`
]

GatsbyやNext.jsで使う

下記の記事で導入する手順をまとめています。

Emotionで動的にスタイル変更する

ReactでEmotionを使って動的にスタイル変更する方法は下記でまとめています。

Emotionの色々な使い方

Emotionで疑似要素やtransitionを使う方法は下記でまとめています。

vscode の拡張機能

  • emotion-auto-css
  • VScode React Emotion Snippets

参考

新着記事

top