VueのTransitionタグを理解する
Vueには、CSSのtransition
プロパティを制御する<Transition>
タグがあります。この<Transition>
タグの使い方と、代替となるTailwindを使った書き方を見ていきます。
transition
プロパティとは
CSSの要素のフェードイン/アウト、スライドイン/アウトなど、単純なアニメーションの記述に使用できるプロパティ。CSSのあるパラメータが動的に変化するとき(要素の表示/非表示切り替えや、hover時の背景色の変化など)に、その変化を補完するアニメーションを記述するものです。
opacity
が動的に変化する例(トランジションなし):
クリックで表示/非表示が切り替わる要素の例です。
ここでは、ボタンがクリックされるたびに、opacity: 0;
を指定したhidden
クラスをつけたり外したりすることで、表示/非表示を切り替えています。
opacity
が動的に変化する例(トランジションあり):
このbox
クラスにtransition
プロパティを指定すると、変化を補完するアニメーションが描画されます。つまり、opacity
が0から1になったり、1から0になったりする変化をアニメーションで繋いでくれます。
なお、transition
と似たプロパティにanimation
があります。
transition
プロパティで記述できるのは一方向のシンプルなアニメーションですが、animation
プロパティでは複雑な変化や繰り返しの指定が可能になります。
<Transition>
タグとは
さきほどの例ではopacity
を使った表示/非表示制御をしましたが、Vueではこのような制御を動的に行う場合v-if
やv-show
を使うことが一般的です。
v-showを使った表示制御の例:
このv-if
/v-show
を使う場合、先程のようなクラスの付け替えではトランジション効果を追加することができません。
v-if
の場合は非表示時に要素自体がDOMから削除され、またv-showの場合は非表示時にdisplay: none;
が適用されるため、表示↔非表示の切り替えの際のプロパティの変化が離散的になります。
transition
プロパティはopacity
やtransform
のような、連続的な値を持つプロパティの変化を補完するものなので、これらの制御といっしょに使うことはできません。
この、v-if
, v-show
を使った制御にトランジション処理を付与したい場合に使用するのが<Transition>
タグです。
<Transition>
タグを使用して、v-show
を使っている要素にトランジション処理を追加した例:
<Transition>
タグにname="fade"
を指定して、fade-*
クラスにトランジション方法を記述することで、トランジション効果を追加しています。<Transition>
タグの詳しい使い方はドキュメントを参照ください。
トランジション | Vue.js
Tailwindクラスを使った代替手段
この<Transition>
タグを使用したアニメーションを実装してfindの社内レビューに出したところ、あえてv-show
を使わずにTailwindクラスの付け替えでopacity
等のプロパティを制御する方法を提案されました。
Tailwindクラスの付け替えでトランジション効果を記述する例:
<Transition>
タグとv-show
を使用した場合の、トランジションに関連する記述は以下です。
<template>
<Transition name="fade">
<div class="box" v-show="show">hello</div>
</Transition>
</template>
<style>
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
</style>
一方、Transitionを使わずに、tailwindのクラスの制御で対応している例は以下です。
<template>
<div
class="box transition-opacity duration-500"
:class="{ 'opacity-0 pointer-events-none ': !show }"
>
hello
</div>
</template>
メリットとしては以下があります。
- コード量が少なく済む
- CSSの記述がtemplate部分のみで完結するので、何をしているか読み解きやすい
-
<style>
部分まで移動しなくてよくなる。行数の多いVueファイルになると、該当するスタイルを見に行って戻ってきて、は面倒だったりしますよね。
-
- トランジションしたい要素の外側をTransitionタグで囲わなければいけないのは直感的に違和感がある。(ある要素の効果はその要素自体に記述したい気持ち)
一方で以下のようなデメリットもあると思っています。
-
v-show
を使っていないのに動的に表示が制御されるのは直感的でない - アニメーションを付けたい箇所には逐一
transition-opacity duration-500
のようなおまじない書く必要があり、冗長かつ記述量も多くなる[1]
複数箇所で同じトランジション効果を使っている場合は、<Transition>
タグを使ったうえで、共通で読み込まれるCSSにスタイルを定義するほうがシンプルに書けそうです。例えばname="fade"
とする場合のfade-*
クラスの共通のCSSファイルに記述するとか。
今回のTailwindで直接指定する方法は、そういった共通化するまでもないような、トランジションの少ないプロジェクトでは選択肢となりそうです。
Discussion