GatsbyJS + Material-UIのブログにCSS in JSのEmotionを導入する

GatsbyJS + Material-UIのブログにCSS in JSのEmotionを導入する
Photo by Joshua Hoehne / Unsplash

このブログの見た目はMaterial UIをベースにstyle属性を使って調整していましたが、RichLinkコンポーネントを作った際にどうしても画面の小さいスマホ用のスタイルと画面の大きいPC用のスタイルを分ける必要が出てきました。

style属性のままだとMediaQueryが使えないので今回はEmotionを導入することにしました。

手順

①必要なNPMパッケージをインストールする

yarn add @emotion/core emotion-theming gatsby-plugin-emotion
# or
npm install @emotion/core emotion-theming gatsby-plugin-emotion

②gatsby-plugin-emotionを読み込む

module.exports = {
  <!-- 中略 -->
  plugins: [
    'gatsby-plugin-emotion',
  ],
}

③emotion-themingを使えるようにする

// 中略
import { MuiThemeProvider, createMuiTheme } from '@material-ui/core'
// highlight-start
import { ThemeProvider } from 'emotion-theming'
// highlight-end

// テーマを作る
export const theme = createMuiTheme({
  palette: {
    primary: {
      main: '#556cd6',
    },
    secondary: {
      main: '#19857b',
    },
  },
})

export const Layout: React.FC = ({ children }): JSX.Element => {
  return (
    <>
      <MuiThemeProvider theme={theme}>
        // highlight-start
        <ThemeProvider theme={theme}>
        // highlight-end
          <CssBaseline />
          {children}
        // highlight-start
        </ThemeProvider>
        // highlight-end
      </MuiThemeProvider>
    </>
  )
}

④あとは使うだけ

import { css } from '@emotion/core'

export const Hogehoge: React.FC = () => (
  <div
    css={theme =>
      css({
        margin: '1rem 0',
        {/* 600pxよりも大きい画面の場合にwidth:'80%'を指定しています */}
        [theme.breakpoints.up('sm')]: {
          width: '80%',
        },
      })
    }
  >
    Hogehoge
  </div>
)

おわりに

今回は既にstyleをオブジェクト記法で書いていたのでEmotionでもオブジェクト記法を使っていますが、タグ付きテンプレートリテラルを使えば従来のCSSのまま書けるので使いやすい方で良いかと思います。