ウィンドウサイズ変更時におけるハンバーガーメニューのチラつきを解消する

初めまして!
昨年12月に未経験で入社しました、フロントエンドエンジニアのきっしゃんです。

エンジニア

きっしゃん

先日、Chromeのデベロッパーツールでハンバーガーメニューの表示確認をしていると、
ハンバーガーメニューである三本線をクリックした時に本来表示されるメニューがブレイクポイントでチラ見えしている状況を発見してしまいました、、、。

イメージ的には下記のような感じです。

最終的にはJavaScriptのリサイズイベントを使用して解決させたのですが、
これはどうやって解決させようと結構悩んだこともあり、
もしかしたら同じように悩んでいる人も居るかも?と思ったため、
今回はハンバーガーメニューをクリックした際に表示されるメニューがウィンドウサイズ変更時に生じるチラつきを解消する方法について書きたいと思います。

チラつきを解消したコードの完成形

下記コードがメニューのチラつきを解消した完成形になります。
resizeイベントでウィンドウサイズの変更中はtransitonnoneにしているのがポイントになります。

See the Pen ハンバーガーメニューのチラつき by shota kishimoto (@shota-kishimoto) on CodePen.

ハンバーガーメニューがチラつく原因は?

そもそもハンバーガーメニューをクリックした際に表示されるはずのメニューがブレイクポイントでちらついていた原因は、ハンバーガーメニューに使用しているtransitionにあります。

画面の左右からふわっと出したり、本記事のデモのようにふわっと出現させたりするために、
皆さんもtransitionを使用しているんじゃないかなと思います。

本記事のデモでは下記のように設定していました。


  .header__nav {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    opacity: 0;
    padding-top: 108px;
    background-color: #f97763;
    height: 100%;
    transition: opacity 0.3s ease-in;
  }

実際に上記のtransitonを使用しないようにした場合、
さっきはウィンドウサイズ変更中にチラついていたメニューが一切表示されないようになります。

ということは、ウィンドウサイズの変更中にはtransitionを効かないようにしてあげることで、
ハンバーガーメニューをクリックした際に表示されるメニューのチラつきが解消されることになりますね。

ハンバーガーメニューのチラつきを解消する方法

原因が判明したところで、
本題のチラつきを解消する方法について書きたいと思います。

方法は色々あるかもしれませんが、
僕自身はJavaScriptのresizeイベントを用いて解消しました。
そのコードは下記になります。


  class Resize {

    constructor(target) {
      this.timeoutId;
      this.target = document.querySelector(target);
  
      window.addEventListener("resize", this._resize.bind(this))
    }
  
    _resize() {
      this.target.classList.add("is-resize");
      clearTimeout(this.timeoutId);
      
      this.timeoutId = setTimeout(() => {
        this.target.classList.remove("is-resize");
      }, 500);
    }
  
  }

  new Resize("html");

.is-resize .header__nav {
  transition: none;
}

リサイズ中は.is-resizeをhtmlタグに付与することでその間はtransitionをnoneにし、
リサイズ終了から0.5秒後に.is-resizeを外すというシンプルなものです。
このようにすることで無事にハンバーガーメニューのチラつきを解消させることが出来ました。

上記の例ではnew Resize("html")でhtmlタグに.is-resizeを付与するよう指定していますが、
こちらはbodyタグやクラス名など好きに変えてくださって大丈夫です。

jQueryを使っている人向け

普段jQueryを使っている方もいるかと思うので、
下記にjQueryの書き方で書いた場合のコードも記載しておきます。

jQueryを使っている方はぜひこちらを使ってみてください。


let timeoutId;

$(function() {
  $(window).resize(() => {
    $("html").addClass("is-resize");
    clearTimeout(timeoutId);

    timeoutId = setTimeout(() => {
      $("html").removeClass("is-resize");
    }, 500);
  })
})

こちらも$("html")は好きに変更して使用してください。

最後に

ハンバーガーメニューはサイト制作する際によく用いられるため、
同じような問題に出くわしている方も居るんじゃないかなと思います。

その場合には、ぜひ一瞬transitionを無くすことでチラつきを解決してみてください。

エンジニア大募集中!!

ロジカルスタジオでは、現在エンジニア大募集中です!
採用サイトをリニューアルしたので、ぜひ下記バナーから覗いてみてくださいね!