Emotionを使ってGatsbyでtailwindを使う方法

gatsby-emotion-tailwind-setuptailwind

Gatsby & Emotion & tailwindの環境構築、スタイリング方法についてまとめました。

環境構築が面倒な方は下のコマンドを実行して、Gatsby starterからプロジェクトを作成してください。

gatsby new emotion_tailwind https://github.com/tombo-gokuraku/gatsby-starter-emotion-tailwind

Emotion, tailwindのインストール

まずは下記コマンドでGatsbyのプロジェクトを作ってください。

gatsby new emotion_tailwind

下のコマンドでtwin.macroとEmotion関連パッケージをインストールします。この時、twin.macroと一緒にtailwindcssも入るので特に指定する必要はありません。

npm install --save twin.macro @emotion/core @emotion/styled gatsby-plugin-emotion

インストールが完了したら、gatsby-browser.jsでtailwindcssのbase.min.cssをimportします。

// gatsby-browser.js
import 'tailwindcss/dist/base.min.css'

さらにgatsby-config.jsにEmotionのためのプラグインを設定します。

// gatsby-config.js
module.exports = {
  plugins: [`gatsby-plugin-emotion`],
}

tailwindをEmotionで使うための設定

ここからはtailwindをEmotionで使うための各種設定を説明します。

tailwind.config.jsの設定

tailwindの設定をするにはtailwind.config.jsが必要です。下のコマンドをプロジェクトのルートで実行して、空のtailwind.config.jsファイルを作ってください。

npx tailwindcss init

これで下のような空のtailwind.config.jsファイルが作られました。

module.exports = {
  purge: [],
  theme: {
    extend: {},
  },
  variants: {},
  plugins: [],
}

設定したい場合はtailwindのconfigurationガイドにしたがって設定してください。

Configuration - Tailwind CSS
A guide to configuring and customizing your Tailwind installation.

babelMacrosの設定

package.jsonにbabel macroの設定を追加します。

  "babelMacros": {
    "twin": {
      "config": "./tailwind.config.js",
      "preset": "emotion",
      "hasSuggestions": true,
      "debug": false
    }
  }

"hasSuggestions": trueにしておくと、間違ったクラスを指定した時に、もしかして…のように関連のありそうなクラス名を教えてくれるのでオススメです。

✕ flex-column was not found

Did you mean flex-col?

もっと詳しい環境構築方法については下記記事をご覧ください

twin.macroの使い方

twin.macroでは大きく分けて4つの方法でtailwindのスタイリングができます。

  1. tw prop(tw="hoge")を使う方法
  2. tw tag(tw.button`hoge`)を使う方法
  3. css prop内でcss tagと組み合わせて使う方法(css={[tw`hoge`, css`piyo`]})
  4. styledを使って引数を取りながら使う方法(styled.button(({primary}) => [tw`hoge`, primary && tw`piyo`,])

tw prop(tw="hoge")を使う方法

tw propを使う方法は簡単です。以下のようにtwin.macroをimportしてtwの後にスタイルのクラス名を書いていくだけです。

import 'twin.macro' 
<button tw="px-4 py-2 border-4 border-green-400 border-solid rounded focus:outline-none">
  tw prop
</button>
tw propを使ったボタン

tw tag(tw.button`hoge`)を使う方法

tw tagを使うにはtwin.macroでデフォルトexportされているtwを使います。

import tw from "twin.macro"

const Button = tw.button`
   bg-teal-100
   py-2
   px-4
   rounded
   border-solid
   border-teal-400
   border-4
   focus:outline-none
`
 <Button>tw tag</Button>
tw tagを使ったボタン

tw tagを使った場合、下のようにしてスタイルをextendすることができます。

const ExtendedButton = tw(Button)`
  text-orange-500
`

<ExtendedButton>extended button</ExtendedButton>
extended tw tag button

上の例ではButtonコンポーネントのスタイルはそのままに、colorだけ変更しています。

css prop内でcss tagと組み合わせて使う方法(css={[tw`hoge`, css`piyo`]})

css prop内でcss tagを使用するにはtwin.macroからcssをnamed importします。下は疑似要素を使ってリンクに下線を引くコンポーネントです。

import tw, {css} from "twin.macro"
<a
  href="/"
  css={[
    tw`inline-block text-base text-black`,
    css`
      &::after {
        content: "";
        display: block;
        margin-top: 2px;
        height: 2px;
        background-color: #B2F5EA;
      }
    `,
  ]}
>
  css tag
</a>
css tagを使ってリンクに下線を引く

styledを使って引数を取りながら使う方法(styled.button(({primary}) => [tw`hoge`, primary && tw`piyo`,])

styledを使って引数を受け取れるコンポーネントを作るには下のように書きます。

import tw, {styled} from "twin.macro"

const StyledButton = styled.button(({ large }) => [
  tw`px-4 py-2 bg-teal-200 rounded`,
  large ? tw`text-xl` : tw`text-base`,
])

<StyledButton>normal</StyledButton> 
<StyledButton large>large</StyledButton>
styledを使って引数(large)を受け取って、テキストサイズが変わるボタン

ちなみに引数を受け取るコンポーネントをStringスタイルで書くことは、記事執筆時点では出来ません。詳しくはこちらのIssueをご覧ください。

もしtailwindで指定できるCSSプロパティ以外のCSSを設定したくなった時は、下のようにcssも一緒にimportして使います。

import tw, {css, styled} from 'twin.macro'

const CustomButton = styled.button(({ primary, gradient }) => [
  tw`px-4 py-2 bg-orange-200 rounded transform hover:(scale-110 text-teal-500 font-bold) transition-transform duration-100 focus:outline-none`,
  primary && tw`bg-teal-200`,
  gradient &&
    css`
      background: linear-gradient(to left, lightgreen, orange);
      ${tw`text-white rounded-md hover:text-white`};
    `,
])

// ...

<CustomButton>normal</CustomButton>
<CustomButton primary>primary</CustomButton>
<CustomButton gradient>gradient</CustomButton>
styled custom button

tailwindのthemeを使う("twin.macro": "^1.6.0")

twin.macroのversion1.6.0からtailwindのthemeを呼び出せるようになりました。themeを使うには import { theme } from "twin.macro"のようにthemeをimportします。

例えば、下のようにしてtailwind.config.jsにprimaryとsecondaryのcolorsを追加します。

module.exports = {
  purge: [],
  theme: {
    extend: {
      colors: {
        primary: "#C43BAD",
        secondary: "#46C9E5",
      },
    },
  },
  variants: {},
  plugins: [],
}

css propで呼び出す時は以下のようにします。

<button
  css={[
    tw`px-4 py-2 text-white rounded transform hover:(scale-110 font-bold) transition-transform duration-100 focus:outline-none`,
    css`
      background: linear-gradient(
        to left,
        ${theme`colors.primary`},
        ${theme`colors.secondary`}
      );
    `,
  ]}
>
  ThemeButton
</button>

styledで呼び出す時は下のようにします。

const ThemeButton = styled.button([
  tw`px-4 py-2 text-white rounded transform hover:(scale-110 font-bold) transition-transform duration-100 focus:outline-none`,
  css`
    background: linear-gradient(
      to left,
      ${theme`colors.primary`},
      ${theme`colors.secondary`}
    );
  `,
])
theme button

参考

ben-rogerson/twin.macro
🦹‍♂️ Twin blends the magic of Tailwind with the flexibility of css-in-js - ben-rogerson/twin.macro
tombo-gokuraku/gatsby-starter-emotion-tailwind
Gatsby starter for using Emotion and tailwind. Linting with ESLint and stylelint. - tombo-gokuraku/gatsby-starter-emotion-tailwind

コメント

タイトルとURLをコピーしました