LoginSignup
13
4

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/

13
4
1

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
13
4