LoginSignup
131
110

More than 1 year has passed since last update.

VueでイケてるTransition! fade, slide編

Last updated at Posted at 2018-11-29

前提

この記事は極力VueのAPICSSだけでTransitionアニメーションを実装するという趣旨の元執筆しています。
またtransitionプロパティVueある程度知っていると仮定した上で話を進めていきます。
よく知らないという方はこちらを閲覧してから、この記事を閲覧することをオススメします。

注意

この記事はデモにCodePenを使用していますが、transitionに必要なCSSを判別しやすくするため、transition関連のスタイルはCSSの欄に、それ以外のスタイルはHTML<style>タグに書いています。
あまり褒められたやり方ではないので、本番環境では真似しないでください

まず初めに

Vueではv-ifv-showに真偽値を入れてやることで、要素の表示と非表示を切り替えることができます。
しかし、その要素にCSStransitionプロパティを設定してやっても、上手く実行されません。
Vueには<transition>というラッパーコンポーネントが用意されていて、これでtransitionさせたい要素を囲むことで上手くtransitionが実行されます。

詳しくはこちらを参照してください => Enter/Leave とトランジション一覧

transition.vue
<template>
  <transition name="fade">
    <div v-if="show">
      Fade
    </div>
  </transition>
</template>

<transition>コンポーネントで囲むことでCSSクラスが付与されます。

transition.vue
<style scoped>
.fade-enter-active, .fade-leave-active {
  /* 表示されている際のCSSはこのブロックに記述 */
}
.fade-enter, .fade-leave-to {
  /* 非表示の際のCSSはこのブロックに記述 */
}
</style>

付与されるクラス名は<transition>nameで指定した値によって変わります。
具体的には上記のクラス名のfadeの部分がそれに当たります。
例えばnameに指定した値がslideだった場合は

transition.vue
<style scoped>
.slide-enter-active, .slide-leave-active {
  /* 表示されている際のCSSはこのブロックに記述 */
}
.slide-enter, .slide-leave-to {
  /* 非表示の際のCSSはこのブロックに記述 */
}
</style>

の様になります。

ちなみにラッパーコンポーネントは、最終的なDOMには表示されないので、階層に気を付けなくても大丈夫です!

Fade

FadeTransitionアニメーションの中でも非常にシンプルでポピュラーな物です。

fade.css
.fade-enter-active, .fade-leave-active {
  will-change: opacity;
  transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
}
.fade-enter, .fade-leave-to {
  opacity: 0
}

Fadeの実装に必要なスタイルは上記の様になります。

will-changeについて

Fadeを実装する上で、このプロパティは必要ありません。
ではなぜこのプロパティが記述されているのか?
will-changeはブラウザにどの要素の変更がよそされるのかを通知し、ブラウザはその通知を元に最適化を行います。
これにより応答パフォーマンスが向上します。

will-changeの使用に関する注意

今回は紹介の為に使用しましたが、will-changeはいいことばかりではありません。
近年のブラウザは何も指定せずともできる限り、最適化を行っており、will-changeをいたずら複数指定することは、必要以上のマシンリソースを消費してしまいます。

あくまで、ページの表示が遅いサイトの応答パフォーマンスを向上させるための最終手段として使用することをオススメします。

詳しくはこちらをご覧ください

Top Slide

これから紹介するslide系TransitionはWebページにちょっとした遊び心を加えます。
ただし、使いすぎるとユーザーに鬱陶しさを与えます。
使いどころとしてはトースト通知などがあるでしょう。

TopSlide.css
.top-enter-active, .top-leave-active {
  transform: translate(0px, 0px); 
  transition: transform 225ms cubic-bezier(0, 0, 0.2, 1) 0ms;
}

.top-enter, .top-leave-to {
  transform: translateY(-100vh) translateY(0px);
}

transform

slide系transitionではtransformプロパティが重要になってきます。
transformプロパティはその名前の通り要素の回転、拡大縮小、傾斜、移動を行うことができます。

詳しくはCSS3クイックリファレンスMDN web docsをご覧ください

vhとは?

上記のCSSをコピペで使用する場合は注意が必要です。

.top-enter, .top-leave-to {
  transform: translateY(-100vh) translateY(0px);
}

-100vhと指定していますが、このvhを見慣れないビギナーの方もいると思います。
このvhとはviewport heightの略称で、要は表示されている範囲をさしています。
上記の例で言えば100vhview portの高さと同じ高さの数値を得る。所謂パーセンテージなのです。
これを正常に動作させる為にはhtml<head>要素の中に以下の<meta>要素を記述する必要があります。

index.html
<meta name="viewport" content="width=device-width, initial-scale=1.0">

最近の高性能なエディタを使っていればhtmlファイルを作ったらすでに書いてあったという人もいると思います。

viewportを元に計算する単位は全部で4つ存在します。

単位 略称元 効果
vh viewport height ビューポートの高さに対する割合
vw viewport width ビューポートの幅に対する割合
vmin viewport minimum ビューポートの幅と高さのうち、値が小さい方に対する割合
vmax viewport max ビューポートの幅と高さのうち、値が大きい方に対する割合

%と何が違うの?

誰もが一度は使う%は親の値に依存しています。
例えば親がheight: 400pxだとすれば、%は親のheightを元に計算されてしまいます。
そこで、どの階層にいても親要素に関係なく、Webページの表示領域のheightwidthを元に計算したいと行った場合にvhvwを使うと期待通りの効果が得られるでしょう。

Top Left Slide

TopLeftSlide.css
.top-left-enter-active, .top-left-leave-active {
  transform: translate(0px, 0px); 
  transition: transform 225ms cubic-bezier(0, 0, 0.2, 1) 0ms;
}

.top-left-enter, .top-left-leave-to {
  transform: translateY(-100vh) translateX(-100vh);
}

Top Right Slide

TopRightSlide.css
.top-right-enter-active, .top-right-leave-active {
  transform: translate(0px, 0px); 
  transition: transform 225ms cubic-bezier(0, 0, 0.2, 1) 0ms;
}

.top-right-enter, .top-right-leave-to {
  transform: translateY(-100vh) translateX(100vh);
}

Bottom Slide

BottomSlide.css
.bottom-enter-active, .bottom-leave-active {
  transform: translate(0px, 0px);
  transition: transform 225ms cubic-bezier(0, 0, 0.2, 1) 0ms;
}

.bottom-enter, .bottom-leave-to {
  transform: translateY(100vh) translateY(0px);
}

Bottom Left Slide

BottomLeftSlide.css
.bottom-left-enter-active, .bottom-left-leave-active {
  transform: translate(0px, 0px);
  transition: transform 225ms cubic-bezier(0, 0, 0.2, 1) 0ms;
}

.bottom-left-enter, .bottom-left-leave-to {
  transform: translateY(100vh) translateX(-100vh);
}

Bottom Right Slide

BottomRightSlide.css
.bottom-right-enter-active, .bottom-right-leave-active {
  transform: translate(0px, 0px);
  transition: transform 225ms cubic-bezier(0, 0, 0.2, 1) 0ms;
}

.bottom-right-enter, .bottom-right-leave-to {
  transform: translateY(100vh) translateX(100vh);
}

Left Slide

LeftSlide.css
.left-enter-active, .left-leave-active {
  transform: translate(0px, 0px);
  transition: transform 225ms cubic-bezier(0, 0, 0.2, 1) 0ms;
}

.left-enter, .left-leave-to {
  transform: translateX(-100vw) translateX(0px);
}

Right Slide

RightSlide.css
.right-enter-active, .right-leave-active {
  transform: translate(0px, 0px);
  transition: transform 225ms cubic-bezier(0, 0, 0.2, 1) 0ms;
}

.right-enter, .right-leave-to {
  transform: translateX(100vw) translateX(0px);
}

demo(CodePen)

See the Pen CSS Transition by マテリアルお兄さん (@nexus0831) on CodePen.

最後に

いかがだったでしょうか?
基本となるFadeと全部で8方向からのSlideを今回は実装してみました。
ダイアログアラート通知を出す際にこれらが使えると、少しばかりユーザーに楽しさを与えることができるでしょう。
少なくとも私は何度も押してしまう位には好きです(笑)

131
110
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
131
110