Fixedした要素がEdgeやIEのスムーススクロールのセイでガクガクする問題を解決!


2018.01.12

リッチコンテンツを作る場合、背景全体に写真やアニメーションを表示させるのに便利なのがCSSの「position:fixed」です。
他にもヘッダーやメニューを固定したい時や、要素をスクロールに関わらず画面内に留まらせる事ができる便利な命令です。

Google Chromeやsafariのようなモダンブラウザなら問題ないのですが、この機能をEdgeやInternet Explorer(以下、IE)で使うと、「fixed」にした要素がマウスホイールを回すたびに"ガクガクブルブル"と震えてしまいます・・・。
せっかくバグとイレギュラー仕様満載のIEが終わって、無駄な対策に時間を割かなくて良くなると思ったのに、Edgeにも地雷を色々埋め込んでいますね・・・。
個人的にはWindowsを使う事はあまりないのですが、お客様の手前、ブラウザのセイにして逃げるわけにもいきませんし、見栄えの良いフルスクリーンの背景表示を要求される事は多いです。
しかし、この「fixed」問題は2017年現在でも放置で、今のところ有効な対策方法がありません・・・見栄えが悪いので、なんとか対応したいところ。

Windowsの機能が根本的な原因

背景要素のz-indexがマイナス値になっている事が原因と書かれたサイトもありますが、私の場合はマイナス値は使う事がないので、このケースには当てはまりませんでした。

色々調べてみると、根本的な原因はWindowsのスムーススクロール機能が働くためなので、これをオフにすれば解決できるのですが、デフォルトでオンになっている上に、かなり分かりにくい場所に設定項目があります。
WEBサイトを見てもらうだけなのに、わざわざユーザーにその作業を強いるのも好ましくありませんね。

「overflow: hidden」でスクロールをさせない

まず最初はhtmlを「overflow: hidden」としてスクロールをさせない事で「fixed」問題を解決しています。
bodyは「overflow: auto」で指定しているので、スクロール自体は可能です。
ただ、この方法だとページ内リンクやスクロールに関する処理が使えなくなりますね・・・

html{
 width:  100%;
 height: 100%;
 overflow: hidden;
}

body{
 width:  100%;
 height: 100%;
 overflow: auto;
}


ちなみに、下記のサイトの場合はトップでのページ内リンクは不使用にして、サイドに表示されるブログや写真ギャラリー等のページ内リンクはdiv内の擬似スクロールで行っております。

ホイールイベントをオーバーライドしてしまおう

パララックスを多用したかったり、スクロールで色々イベントを起こしたい場合は上の方法は使えません・・・。
なので、EdgeとIEの場合にのみホイールイベントを乗っ取ってしまおうと思います。
ブラウザやOSのスクロール機能を使わずに、イベントとスクロール量だけを取得して、Javascriptでページをスクロールさせる事ができればWindowsのスムーススクロールを使わなくて良くなります。
コロンブスの卵的な発想ですが、この方法でガクガクスクロールからは解放されました。

$(function(){
    ScrollLength = 200;
    ScrollSpeed = 500;
 
    var mousewheelevent = 'onwheel' in document ? 'wheel' : 'onmousewheel' in document ? 'mousewheel' : 'DOMMouseScroll';
    $(document).on(mousewheelevent,function(e){
        e.preventDefault();
        var delta = e.originalEvent.deltaY ? -(e.originalEvent.deltaY) : e.originalEvent.wheelDelta ? e.originalEvent.wheelDelta : -(e.originalEvent.detail);
        if (delta < 0){
            ScrollSet =  $(document).scrollTop()+ScrollLength;
        } else {
            ScrollSet =  $(document).scrollTop()-ScrollLength;
        }
        $('html,body').stop().animate({scrollTop:ScrollSet},ScrollSpeed);
        return false;
    });
});


下記のサイトでは、Edgeの場合のみ上記Javascriptが働いて、スムーススクロールを使わずにスクロール可能です。

スクロールの動きがちょっと不自然なので、実際に使われる場合は自分のサイトに合わせて「ScrollLength」と「ScrollSpeed」の値を調整して使ってみて下さい。 今回は行っていませんが、慣性スクロールを取り入れると、元のスムーススクロールっぽい動きも可能です。

Copyright © 2017, Mo-ja.net All Rights Reserved.

関連記事

Fixedした要素がEdgeやIEのスムーススクロールのセイでガクガクする問題を解決!

横並びレイアウトはfloatをやめてFlexboxに切り替えよう!縦中央揃えや「Masonry」の代替にも使えるよ! 基本編 [1]