#ffffff #bc7c43 #beb53f #85a248 #2f6850 #4f8ea4 #89bcc5 #565669 #000000 #b22222 #daa09a

web material *Essence

  1. Home
  2. DesignTips
  3. fixed background bug

Fixed background bug

IE,Edge のスクロール時のガタつき

パララックス(parallax‐視差効果)的なfixed要素(背景画像固定)が、スクロール時にIEとEdgeでガタガタする不具合は、インターネットオプションの「スムーズスクロール」が原因だという問題はよく聞く話になっています。
発生にはいくつかの要因もありますが、他の部位に関係する弊害もあり修正が難しい場合も有ります。
IEでは『インターネットオプション > 詳細設定 > スムーズスクロールを使用する』 のチェックを外すとガタつきは無くなりますが、操作をユーザー側に要請するのはあまり現実的ではありません。
またEdgeは「スムーズスクロール」だけの設定を変更する事ができず、『windowsシステムツール > コントロールパネル > システムの詳細設定 > 詳細設定タブ > パフォーマンス設定 > 一番上の“Windows内のアニメーションコントロールと要素”』のチェックを外すとEdgeのスムーズスクロールはなくなるそうですが、Edge以外も動かなくなります。

参考:EdgeでスムーススクロールをOFF(Yahoo!知恵袋)

スムーズスクロールを無効にして挙動を確認してみました。
windows8.1(F12開発者ツール)ブラウザモードIE10,IE11・ドキュメントモード10,Edge(VMware Workstation)
windows10(同ツール)ブラウザモードIE10,IE11・ドキュメントモード10,11
windows10(同ツール)Edgeユーザーエージェント文字列IE10,IE11,Edge
上記のOS、及びモードでガタつきが収まります。
(windows8は未確認。windows7でIE8~IE11までを実機で検証してみましたが全てガタつきが収まりませんでした。)

  IE6 IE7 IE8 IE9 IE10 IE11 Edge
windowsXP
windowsVista
windows7
windows8
windows8.1
windows10

 デフォルトのIE  ○ インストールできるIE  参考:各Windows OSで利用できるIEのバージョンを知る

スムーズスクロールを無効にする

ユーザーエージェントでIE10,IE11とEdgeを判別し、ページを閲覧中はJavaScriptでスムーズスクロールを無効にします。

if(navigator.userAgent.match(/(msie|MSIE) 10/i) || navigator.userAgent.match(/(T|t)rident\/7\./) || navigator.userAgent.match(/Edge\/\d+\.\d+/)) {
  $('body').on("mousewheel", function () {
    event.preventDefault();
    var wd = event.wheelDelta;
    var csp = window.pageYOffset;
    window.scrollTo(0, csp - wd);
  });
}

参考:New bug in IE11 -- scrolling position:fixed + background-image elements jitters badly.
IE、Edgeでposition:fixedな要素がスクロール時にガタつく場合の対応策

上記のスクリプトは、『F12開発者ツール』のドキュメントモード11では問題無いのですが、ドキュメントモード10では“オブジェクトは 'preventDefault' プロパティまたはメソッドをサポートしていません。”と出てガタつきの症状が出てしまいます。
event.preventDefault()メソッドのエラーについて対処方法を探していると、IEの前バージョンにはこれが必要とのこと。
event.returnValue = false;
event.preventDefault(); を event.returnValue = false; に置き換えるとドキュメントモード10では固定されるようになりましたが、ドキュメントモード11ではガタつきが出てしまいました。そのため、ブラウザの違いを考慮して下記のように変更してみます。
(ドキュメントモードとは、HTMLの先頭にある「DTD宣言」の種類やソースコードでレンダリングを切り替える仕組み。)

if(event.preventDefault){
   event.preventDefault();
}else{
   event.returnValue=false;
}

参考:event.preventDefault() function not working in IE

if(navigator.userAgent.match(/(msie|MSIE) 10/i) || navigator.userAgent.match(/(T|t)rident\/7\./) || navigator.userAgent.match(/Edge\/\d+\.\d+/)) {
   $('body').on("mousewheel", function () {
     if(event.preventDefault){
        event.preventDefault();
     }else{
        event.returnValue=false;
     }
    var wd = event.wheelDelta;
    var csp = window.pageYOffset;
    window.scrollTo(0, csp - wd);
  });
}

上記でIE10,IE11,Edge のfixed要素固定が出来ました。
windows7以前のOSをご利用の方は、IEのHTMLレンダリングエンジンTrident(トライデント)は色々とバグも多いので、これを機会にTrident、(Tridentから分岐して開発されたレンダリングエンジン)EdgeHTML以外のブラウザを試してみるのも良いかもしれません。