iOS15のSafariで背景固定のモーダルを立ち上げると、タップ領域が上にずれる

2022年3月時点でiOS15でのみ起きる現象のようです。iOS14では出ませんでした。

タップ領域がずれるタイミング

Safariの上のタブバーが小さくなった状態の時にモーダルを立ち上げると、タブバー分上に領域が上にめり込みます。このバグの厄介な所は、見た目はそのままで領域のみが上にめり込む所です。

iOS15端末をiPadしかもっていないので動画が大きいですが😅

Qiitaでこのバグについて記事を書いている方がいらっしゃったので下記引用。

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

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

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

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

iOS 15 Safari モーダル処理時にスクロール固定のために従来のやり方をするとおかしくなる件 | Qiita
https://qiita.com/norarion/items/337fc6f82e91a8398f23

対応

バグ対応はQiitaの投稿そのままコピペさせていただきましたが、モーダルを立ち上げた時スクロールが一番上へ戻ってしまったので、従来のbodyにfixedをつける対応と合わせるとうまくいきました。

styleTag.innerText = 
 "html.is-locked,html.is-locked body {height: calc(var(--window-inner-height) - 1px);overflow: hidden;box-sizing: border-box;}"

↓
//heightだけにする。
styleTag.innerText =
 "html.is-locked {height: calc(var(--window-inner-height) - 1px);}";
//従来のやり方。 iOS15だとバグる
  const modalSwitch = {
    open: (id) => {
      modalWrapper.classList.add("is-active");
      sessionStorage.setItem("id", id);

      //モーダルをあげている時はスクロール無効とする
      scrollStock = window.pageYOffset;
      body.classList.add("is-locked");
      body.style.top = -scrollStock + "px";
    },
    close: () => {
      //スクロール無効を元に戻す
      body.classList.remove("is-locked");
      body.style.top = "";
      window.scrollTo(0, scrollStock);

      modalWrapper.classList.remove("is-active");
    }
  };
//iOS15対応版。 htmlにもclassを降ってあげる
  const modalSwitch = {
    open: (id) => {
      modalWrapper.classList.add("is-active");
      sessionStorage.setItem("id", id);

      html.classList.add("is-locked");
      //モーダルをあげている時はスクロール無効とする
      scrollStock = window.pageYOffset;
      body.classList.add("is-locked");
      body.style.top = -scrollStock + "px";
    },
    close: () => {
      html.classList.remove("is-locked");
      //スクロール無効を元に戻す
      body.classList.remove("is-locked");
      body.style.top = "";
      window.scrollTo(0, scrollStock);

      modalWrapper.classList.remove("is-active");
    }
  };

参考サイト

iOS 15 Safari モーダル処理時にスクロール固定のために従来のやり方をするとおかしくなる件 | Qiita
https://qiita.com/norarion/items/337fc6f82e91a8398f23

iOS15になって今まで起きなかったバグが起きてきて困ります。モーダル展開時に、従来のbodyをfixedにするプラス、window.innerHeightでhtmlのheightを固定して対応していくのが良さそうです。
話は逸れますが、iOS15だと::-webkit-scrollbarも使えなくなっているので、もしスクロールバー装飾する場合はjs使った方が良さそうですね。