現在、エビスコムさんの「作って学ぶ Next.js/React Webサイト構築」を参考にポートフォリオを作成しています。
今回は、サイト制作に使用するスタイリング方法の一つであるEmotionについての覚書です。
CSS modules から Emotion に移行
本書はスタイリング方法としてCSS modulesを使用しています。
HTML/CSS経験者なら同じように書くことができるので初心者向けといえます。
ですが、ある程度進んだところでファイル数の増大が気になり始めました。
CSS modulesの特徴としてコンポーネントごとにCSSファイルを分割するので、必然的にファイル数が倍になるのです。
作っているサイトデザインもそれほど複雑ではありません。
セレクタも1ファイルで数えられるくらいしかないのにわざわざ分ける必要はあるのかと疑問に思いました。
Emotionでスタイルを定義するには以下のように書きます。
const App = () => {
return (
<div css={hello}>こんにちは!</div>
)
}
export default App
const hello = css`
font-size: 1.5rem;
color: red;
`
見てわかるようにコンポーネントと同じファイルにまとめてスタイルを書くことができます。
規模によりますが、小規模サイトなら圧倒的にEmotionが楽だと思います。
Emotion の導入
では、Emotionをインストールしましょう。
npm install @emotion/react @emotion/babel-plugin
or
yarn add @emotion/react @emotion/babel-plugin
@emotion/babel-plugin
はEmotionをコンパイルするプラグインです。
Babel の設定ファイルの作成
.babelrc
を作成して以下を追加します。
{
"presets": [
[
"next/babel",
{
"preset-react": {
"runtime": "automatic",
"importSource": "@emotion/react"
}
}
]
],
"plugins": ["@emotion/babel-plugin"]
}
JavaScriptで書く場合は、ここまででEmotionの環境構築完了です。
TypeScript の場合(型定義の追加)
tsconfig.json
に以下を追加します。
"compilerOptions": {
"types": [
"@emotion/react/types/css-prop"
],
}
これがないと、CSS Propにスタイルを渡すときにエラーが出ます。(以下例)
Emotion の命名規則
すでにEmotionを使えるようになりましたが、命名規則についても語っておきます。
私はこちらの記事を参考にクラス名を決めました。
Next.jsでサイト制作をする場合、コンポーネントごとに大体パターンが決まってくるので使うクラス名も限られてきます。
先にルールさえ決めてしまえば迷うこともなくなり制作もスムーズです。
stack
記事一覧など繰り返し処理を囲むのに使用します。
stackは直訳すると積み重ねるという意味です。
wrapper / inner
ブロック要素を囲むのにwapper、中の要素にinnerを使用します。
group
類似するコンポーネントを囲むのに使用します。
holder
groupと似ていますが、こちらは異なる種類のコンポーネントをグループ化するのに使用します。
例:Contactコンポーネントのフォームとボタンなど
list / item
全体を覆う要素(ul)にlist、子要素(li)にitemを使用します。
Emotion の基本的な使い方
では、Emotionの基本的な使い方を見ていきましょう。
- CSSモジュールをインポート
- 変数でスタイルを定義
- CSS Propでスタイルを呼ぶ
の流れで使用します。
import { css } from '@emotion/react'
const App = () => {
return (
<>
<h1 css={h1Style}>これは見出しです!</h1>
<p css={pStyle}>本文です!</p>
</>
)
}
export default App
const h1Style = css`
font-size: 2rem;
color: red;
`
const pStyle = css`
font-size: 1rem;
line-height: 1.5;
`
メディアクエリの使い方
メディアクエリも変数内で使用できます。
const h1Style = css`
font-size: 1.5rem;
color: red;
// PCの場合
@media (min-width: 768px) {
font-size: 2rem
}
`
CSS を extend する方法
次にスタイルをextend(継承)する方法を見ていきます。
Emotionでは、CSS modulesのcomposeによるextendはできません。
同一ファイルから extend
同ファイル内で継承する場合は、以下のようにします。
const parentStyle = css`
font-size: 1.5rem;
font-weight: 400;
line-height: 1.7;
color: red;
`
const childStyle = css`
${parentStyle} // parentStyleを継承
color: blue; // colorだけ上書き
`
これでカラーだけ青になったchildStyleを作ることができます。
注意として、親になるスタイルは子より上に書かないとエラーになります。
ベースファイルを作って extend
おすすめの継承方法として、別ファイルにベーススタイルを作成し呼び出すという方法もあります。
似たスタイルをいろんなコンポーネントで継承して使いまわすときに便利です。
stylesフォルダを作り、base.js
(好きな名前でOK)を作ります。
エクスポートするのを忘れないようにしましょう。
import { css } from '@emotion/react'
export const baseTextStyle = css`
font-size: 1.5rem;
font-weight: 400;
line-height: 1.7;
color: red;
`
ベーススタイルをインポートすれば、ほかのファイルで継承して使うことができます。
import { css } from '@emotion/react'
import { baseTextStyle } from 'styles/base'
const App = () => {
return (
<>
<h1 css={extendTextStyle}>継承されたスタイルです!</h1>
</>
)
}
const extendTextStyle = css`
${baseTextStyle}
color: blue;
`
今回紹介した、基本形、メディアクエリ、継承くらいで小規模サイト程度なら困ることはないかと思います。
参考になれば幸いです。