2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

クランチタイマー株式会社Advent Calendar 2021

Day 9

透過アニメーション 成功と失敗集

Last updated at Posted at 2021-12-09

やろうとしたこと

前提固定ヘッダーにボタン押下でナビゲーションメニューを開閉する仕組み
(いわゆるハンバーガーメニュー)
その開閉時の視覚効果を「スーッと消えたり現れたりする透過アニメーション」にする

失敗集

その1

html
<button class="menu-btn type="button" title="メニュー" aria-expanded="false">MENU</button>
<div class="menu">
   # 以下グローバルメニューの中身
</div>
js
document.querySelector('.menu-btn').addEventListener('click', function () {
    document.querySelector('.menu').classList.toggle('is-active');
    if (this.getAttribute('aria-expanded') == 'false') {
         this.setAttribute('aria-expanded', true);
    } else {
         this.setAttribute('aria-expanded', false);
    }
});

scss
.menu {
   opacity: 0;
   transition: all 0.5s ease-out;
   &.is-active {
      opacity: 1;
   }
}

結果:アニメーションは期待通りになるが、ヘッダーのリンクが機能しなくなった。
原因:透過しても、要素自体が無くなる訳ではないのでそれらが重なってしまった。
対策:displayの値を切り替える
↓↓↓

その2

scss
.menu {
   display: none;
   opacity: 0;
   transition: all 0.5s ease-out;
   &.is-active {
      display: block;
      opacity: 1;
   }
}

結果:リンクが機能しなくなる問題は解決したが、今度は透過アニメーションが作動せず。
原因:期待する挙動が
①display:noneを解除(この時点でopacity:0)
②n秒かけてopacityを1にする
であるのに対し、CSSファイルは上から順に指示をされるため
transitionが適切なタイミングで実行されない
対策:jQueryの@keyframesを使えば、アニメーションを自由に定義できるとのこと。
display:noneの解除後に@keyframesを読み込んでアニメーションを実行させる
↓↓↓

その3

scss
@keyframes fadeIn {
  0% {
     opacity:0;
  }
  100% {
     opacity:1;
  }
}

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

.menu {
   animation-name: fadeOut;
   animation-duration: 0.6s;
   animation-timing-function: ease-out;
   animation-fill-mode: forwards; 
   display: none;
   &.is-active {
      display: block;
      animation-name: fadeIn;
      animation-duration: 0.6s;
      animation-timing-function: ease-out;
      animation-fill-mode: forwards;
   }
}

結果:動きました!但し、アニメーションが適用されたのはフェードインの方だけ。
原因:.is-activeというクラス名を付与した際は有効だが、
除去したタイミングにはcssの再読み込みはされないから?? 
この問題について解決策を見つけることは出来ませんでしたが、
色々調べていく中で今回自分が実現したかったことは
jQueryのfadeToggleと同一のものだと分かりました。
cssは不要です。
↓↓↓

最終的なコード

js
document.querySelector('.menu-btn').addEventListener('click', function () {
         $('.menu').fadeToggle(1000); // この一文を追加
         document.querySelector('.menu').classList.toggle('is-active');
         if (this.getAttribute('aria-expanded') == 'false') {
            this.setAttribute('aria-expanded', true);
         } else {
            this.setAttribute('aria-expanded', false);
         }
      });
2
0
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
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?