LoginSignup
3

More than 1 year has passed since last update.

iOS 15 Safari モーダル処理時にスクロール固定のために従来のやり方をするとおかしくなる件

Last updated at Posted at 2021-11-18

##現象

モーダル表示される時に普段はoverflow hiddenして、スクロールさせない様にしてますが、iOSはoverflow hiddenしてもスクロールされるためbodyにfixedし、ずれた分のScrollTopからの位置をあてて対応してました。

ところがiOS15にてその対応を行っているページで不具合が発生しました。

どうやらbodyにfixedすることでiOSで新たに追加された機能(タブバー)のせいなのかわかりませんが、bottomの基準位置が見た目とズレちゃうみたいなんですよね。

これがどういう状況で起こるかというと、下記に該当している場合です。

1.ページ下部にナビゲーションをfixedで置いている。(bottom: 0;など。)
2.modalなどの処理でbodyまたはhtmlにfixedしている時。

modalを開いてbody fixedしてスクロールを固定させると既に置いているページ下部のナビゲーションがタブバーの高さ分?隙間が出ちゃいます。

##対処法
とりあえずコードを。

class Ios15ModalHack {
  constructor() {
    this.init();
    this.load();
    this.resize();
  }
  init() {
    const styleTag = document.createElement('style');
    styleTag.innerText = "html.is-locked,html.is-locked body {height: calc(var(--window-inner-height) - 1px);overflow: hidden;box-sizing: border-box;}"
    document.getElementsByTagName('head')[0].insertAdjacentElement('beforeend', styleTag);
  }
  syncHeight() {
    document.documentElement.style.setProperty (
      "--window-inner-height",
      `${window.innerHeight}px`
    );
  }
  load() {
    window.addEventListener('load', () => {
      this.syncHeight();
    });
  }
  resize() {
    window.addEventListener('resize', () => {
      this.syncHeight();
    })
  }
}
const App = new Ios15ModalHack();

headに必要なstyleをjs側で挿入して、
モーダル発火時にそのクラス( html.is-locked )をつけることで謎の隙間を防止します。
fixedは使いません。

内容としてはモーダル展開時にスクロール量が内部的にあると起こる?らしいので
発火時にはwindow.innerHeightでhtmlのheightを固定してしまおうという内容です。
CSS側で

height: calc(var(--window-inner-height) - 1px);

と謎の1pxを引いてますが、これが無いと展開時に垂直スクロールでタブバーの誤動作が起きて不具合が起きるそうです。

iOS15は他にも不具合ありそうなので注意が必要ですね...。

下記参考させていただきました。
https://pqina.nl/blog/how-to-prevent-scrolling-the-page-on-ios-safari/

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
What you can do with signing up
3