🐧

Tailwind CSSに独自のkeyframesとanimationを作る

2022/02/26に公開

Tailwind CSSにはデフォルトでいくつかアニメーションが用意されています。

animate-とクラス指定することで使えます。

ですが、それはあくまで役立つ例であると、公式にも書いてあります。

Tailwind CSSのアニメーション機能は自分でカスタマイズしたものを作った時に本領を発揮するのだと思います。

カスタマイズ方法は以下の公式に載っています。

https://tailwindcss.com/docs/animation

忘れないように自分用メモとして例を残しておきます。

アニメーションのcss

普通にCSSで書くなら以下のような形です。

.appear {
  animation: appear 1.5s ease 2s 1 forwards;
}

@keyframes appear {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

keyframesを設定する

Tailwind CSSで使えるようにするには、tailwind.config.jsに記述を追加します。

デフォルトのanimationは消さずに独自のアニメーションを追加したいので、theme内のextendの中にkeyframesを作成します。

tailwind.config.js
module.exports = {
  mode: "jit",
  content: [
    "./pages/**/*.{js,ts,jsx,tsx}",
    "./components/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {
      keyframes: {
        appear: {
          "0%": { opacity: 0 },
          "100%": { opacity: 1 },
        },
        disappear: {
          "0%": { opacity: 1 },
          "100%": { opacity: 0 },
        },
      },
    },
  },
  plugins: [],
};

上は複数含めた場合です。

appearの部分がkeyframesのnameになります。

animationを設定する

tailwind.config.js
module.exports = {
  mode: "jit",
  content: [
    "./pages/**/*.{js,ts,jsx,tsx}",
    "./components/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {
      keyframes: {
        appear: {
          "0%": { opacity: 0 },
          "100%": { opacity: 1 },
        },
        disappear: {
          "0%": { opacity: 1 },
          "100%": { opacity: 0 },
        },
      },
      animation: {
        appear: "appear 1.5s ease 2s 1 forwards",
        disappear: "disappear 3s ease 0s 1 forwards",
      },
    },
  },
  plugins: [],
};

keyframesと同様にextendの中にanimationを追加します。

先ほど作成したkeyframesのnameを使用することができます。

このように、animationの設定をtailwind.config.jsに入れることで、animate-appearと入れることで設定したアニメーションをクラスで指定することができます。

似たような動作はstateの更新でも可能

例に上げた表示や非表示のアニメーションは、animationを使わなくても、stateの切り替えで似たようなものが実装出来ます。

以下のような感じです。

onclickなどでstateが変わるなどして、stateを変更することで、表示と非表示が変わります。

display:noneではないので、アニメーションも効きます。

//抜粋
const classNames = (...classes) => {
  return classes.filter(Boolean).join(" ");
};
//
<div
  className={classNames(
    isActive
      ? `visible opacity-100 duration-[1500ms] delay-[2000ms]`
      : `invisible opacity-0 duration-[3000ms]`,
    "text-base font-bold"
  )}
>
  テキスト
</div>

表示非表示ぐらいだったらできてしまうけど…

animationを使わなくてもReactとTailwind CSSの組み合わせで、似たようなものは意外とできてしまうのですが、animationを使う利点もあります。

animationの利点は、keyframesでの設定ができることです。表示非表示だったとしても、個別にアニメーションを作る場合はkeyframesで可能な細かい動作の指定ができます。

animationの設定の中では、CSSで用意されている設定を使えるため、Tailwind CSSでは数値を指定しないと使えないeasing-functionなども使用できます。

まとめ

最初はプレーンのCSSでアニメーションを書いてCSSモジュールで読み込んでいたのですが、Tailwind CSSのクラスをstateで切り替えた時にアニメーションをしたくなりまして。

単純に消したり出したりだけならば、stateの切り替え時にopacityの値を変えるだけで良いのですが、CSSモジュールを使ってちょっと複雑なことをやろうとしたら上手くできませんでした。

実現しようとした機能は、ページ読み込み時は透明で数秒後に時間差で表示され、かつ、stateが変更になった時には一度消えて移動してまた出現するという動作でした。これがCSSモジュールの読み込みだけではなかなか上手くいかずでして…。

CSSモジュールとTailwind CSSのクラスを併用する方法がパッと思いつかなかったので、Tailwind CSSで独自のアニメーションを作って、それを切り替える方法を試したのですが、その時にanimationの設定を勉強したので、そのメモになります。

一つ便利だったのが、Tailwind CSSのVSCodeプラグインを入れておくと、自分で設定したクラスもサジェストされたことです。これ、良いですね~。サジェストに出るのはとても便利なので、各プロジェクトごとにアニメーションを設定しておけば使いまわしもしやすくて便利かなと思いました。

Discussion