当サイトは、アフィリエイト広告を利用しています
当ブログを作成するにあたりCSS in JSのEmotionを使ったので
基本的な使い方を忘備録として残す。
またブログの実装で使ったサンプルもまとめておく。
TypeScriptで使う場合については下記記事にてまとめています。
Emotionには大きく
の三つがある。
バッククォートを使った一番基本的な書き方。
私もこの書き方で実装しています
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と同じ様にコードを書くことができるので
馴染みやすいと思います。
オブジェクトスタイルで書く。 オブジェクトスタイルで書く場合、下記のような注意点がある
import { css } from '@emotion/react'const bgcolor = "#666666";const Box2 = css({width: "200px",height: "100px",backgroundColor: "green",color: "white",})<div css={Box2}>box2</div>
styed-component っぽく書くこともできる
typescriptで書く場合は恩恵がうけられる
styled.div の形で書く
import styled from '@emotion/styled'const bgcolor = "#666666";const Box3 = styled.div`width: 200px;height: 100px;background-color: ${bgcolor};color: white;`<Box3>box3</Box3>
ObjectStyle の形で書く
import styled from '@emotion/styled'const bgcolor = "#666666";const Box4 = styled.div({width: "200px",height: "100px",backgroundColor: "#663399",color: "white",})<Box4>box4</Box4>
EmotionはCSSinJSのため関数にして引数を渡すこともできる
StringStylesで定義したCSSを返却する関数を作り、csspropsを使って
スタイリングするサンプルをまとめる。
CSSの値を動的に記述したい場合はCSS(StringStyles)を返却する関数を
作り、引数を渡すことで実現できる。
css={}の中身は配列でも変数でも設定可能。
※だが配列でないとエラーになるパターンもあるため
基本的には配列の形にしておく。
//関数にする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は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>);
下記に実装サンプルを載せます
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>);
下記に実装サンプルをのせます
条件のよって返却する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>)}
下記に実装サンプルをのせます
csspropsで設定したCSS(StringStyles)を返却する関数を
で判定してから実行させることもできる。
ショートサーキット評価については下記記事でまとめています。
/** @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"><divcss={[css`display: grid;justify-content: center;`]}><h1>インラインで関数を条件付きで実行する</h1><Button /><h1css={[// ショートサーキット評価で判定state && buttonStyle,// 三項演算子で判定// state ? buttonStyle:""css`text-align: center;`]}>Hello Emotion</h1></div></div>);}const buttonStyle = () => {return [css`background-color: skyblue;`];};
下記に実装サンプルをのせます
上記の「StringStylesで関数を使う」では外でStringStylesで関数を定義して
propsで渡していたが、jsx内にインラインで書くこともできる。
書き方としては
css={[css`xxxxx`]}
のように配列の形で受け取る必要がある。
<divcss={[css`display: grid;grid-template-columns: 300px;justify-content: center;background-color: yellow;`]}><h1>Emotion Sample</h1></div>
下記に実装サンプルをのせます
Emotionで定義したcssを複数指定することもできる。
ただ呼び出し側は配列の形で受け取る必要がある。
直書きと一緒に書くこともできる。
// 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>
下記に実装サンプルを載せます
props内でインラインで関数を書いて使うこともできる
下記のような形になる。
<h1css={[() => [css`color: ${flg ? "red" : "blue"};`]]}>hello Emotion</h1>
一応、サンプル載せときます
emotionについては色々な書き方ができるので自分の中で書き方を統一しておいた方が良いです。
下記にサンプルルールを書きます。
const container = ()=>[css`height: 100%;background-color: white;color: red;`,];
基本的に関数の形で戻り値は配列で書いた方いい。引数を追加する場合や
他のcssを取り込む場合などに柔軟に対応できるため。
// 呼び出す側も配列で書く<div css={[container]}><p>current color mode:{colorMode}</p><button onClick={setColorMode}>toggle color mode</button></div>
配列の形で受け取るようにする。色々追加や変更する場合も
配列にしていた方が対応しやすいため。
同じ分類のcssをオブジェクトの形にまとめるようにする。
emotionはCSS in JSなのでjavascriptの書き方で管理できる
/** @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><divcss={[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はサンプルの意味で敢えて関数の形で書いていないが
関数の形で書くこともできる。
// 値を設定styleB: () => [css`text-align: center;width: 300px;color: blue;`],// 疑似クラスを設定styleC: () => [css`&:hover {background-color: rgba(0, 0, 255, 0.5);}`]
下記の記事で導入する手順をまとめています。
ReactでEmotionを使って動的にスタイル変更する方法は下記でまとめています。
Emotionで疑似要素やtransitionを使う方法は下記でまとめています。