はじめに

記事投稿に勤しんでいたある日、その問題は突然発生しました。いや、突然発生したというのは、正しい表現ではないです。その問題は以前からそこにありました。私が気づいていなかっただけです。

投稿全体を止めて、その問題の現象と原因究明に2週間も没頭してしまいました。

結果、記事投稿が完全に停止してしまいました。これは、ひとえに私が自分の探求心を抑えられなかったがために発生したことです。

そこで、せっかくなので、ここでは、その問題の現象と原因についてまとめたいと思います。


まず、その問題とは?

現在、Web サイトのデザインを全面的にリニューアルしております。

そこで、スマホなどの画面の小さな機器に対しても柔軟に対応できるように、viewport の対応をすすめてきました。

その一環として、記事の中で作成したサンプルプログラムのデザインも、画面幅に合わせて柔軟に変更できるよう grid デザイン化をすすめてきたわけです。そんな中、テスト中にその問題に気づきました。

結論からいうと、iOS 26 の iPhone において、サンプルプログラムの <input> タグにフォーカスが移った後、それ以降、位置固定しているはずのメニューヘッダーが上スクロールでスクロールしてしまうという問題です。

下スクロールでは、問題なく、固定化されているので、固定化そのものがはずれてしまっているわけではないようです。


発生する環境

現時点では、iOS 26 を搭載した iPhone で確認しています。

特に、通常のテキスト入力を行う <input> タグにフォーカスした場合に再現します。

<input type="date"> では、現在確認している範囲では発生していません。

また、ピンチイン・ピンチアウトだけでは発生しません。

尚、iPhone 版 Chrome でも同様の現象を確認しています。


問題発生時の実際の画面の確認

では、実際にどのような問題なのか、再現手順に従い、画面をみていただきたいと思います。

※ 画面左上には、デバッグ情報として下記のデータを表示しています。

  • scrollY: window.scrollY の値
  • offsetTop: window.visualViewport.offsetTop の値
  • innerHeight: window.innerHeight の値
  • vv.height: window.visualViewport.height の値

1. 問題発生記事頁の初期表示

問題が発生する画面の頁です。上部メニューバーも固定されており、問題ありません。

(図1)問題発生記事頁の初期表示

■ デバッグ情報

  • scrollY : 0
  • offsetTop : 0
  • innerHeight : 553
  • vv.height : 553

2. サンプルプログラム起動ボタン位置まで下スクロール

<input>タグをもつサンプルプログラムを起動するボタン位置まで移動します。ここでも問題はありません。

(図2)サンプルプログラム起動ボタン位置まで下スクロール

■ デバッグ情報

  • scrollY : 438
  • offsetTop : 0
  • innerHeight : 627
  • vv.height : 627

3. サンプルプログラム表示

ボタンをタップし、サンプルプログラムをポップアップ画面で表示します。ここでも問題はありません。

(図3)サンプルプログラム表示

■ デバッグ情報

  • scrollY : 438
  • offsetTop : 0
  • innerHeight : 627
  • vv.height : 627

4. <input> タグへのフォーカス

<input> タグをタップします。すると画面がズームされ、フォーカスされます。

(図4)<input>タグへのフォーカス

デバッグ情報は、top:0 固定なので、画面外になってしまいます。

5. 画面左上位置に移動

デバッグ情報を表示させる為、画面を左上位置に移動します。

(図5)画面左上位置に移動

■ デバッグ情報

  • scrollY : 375
  • offsetTop : 0
  • innerHeight : 346
  • vv.height : 161.25

6. ソフトキーボードの非表示

ソフトキーボードを閉じて、入力を終了します。(尚、今回確認した範囲では、値を入力してもしなくても同様の結果でした。)

(図6)ソフトキーボードの非表示

■ デバッグ情報

  • scrollY : 375
  • offsetTop : 0
  • innerHeight : 346
  • vv.height : 328.75

7. ピンチイン

ピンチインして、画面をもとのサイズにもどします。

(図7)ピンチイン

■ デバッグ情報

  • scrollY : 0
  • offsetTop : 0
  • innerHeight : 553
  • vv.height : 526

8. 上スクロール

画面を上スクロールすると、top:0 の位置で固定化されていたメニューバーがスクロールされてしまい、画面外に消えてしまいます。

(図8)上スクロール

デバッグ情報は、top:0 固定なので、画面外にスクロールされてしまいます。

9. 下スクロール

すぐにメニューバーが表示され、top:0 の位置で、固定されます。

(図9)下スクロール

■ デバッグ情報

  • scrollY : 15
  • offsetTop : 0
  • innerHeight : 553
  • vv.height : 526

10. 元の記事に戻る

サンプルプログラム外をタップして、プログラムを終了し、元の記事頁に戻ります。

(図10)元の記事に戻る

■ デバッグ情報

  • scrollY : 0
  • offsetTop : 0
  • innerHeight : 553
  • vv.height : 526

11. 元の記事頁での上スクロール

(図11)元の記事頁での上スクロール

画面を上スクロールすると、top:0` の位置で固定化されていたメニューバーがスクロールされてしまい、画面外に消えてしまいます。

デバッグ情報は、top:0 固定なので、画面外にスクロールされてしまいます。

12. 元の記事頁での下スクロール

すぐにメニューバーが表示され、top:0 の位置で、固定されます。

(図12)元の記事頁での下スクロール

■ デバッグ情報

  • scrollY : 0
  • offsetTop : 0
  • innerHeight : 553
  • vv.height : 526

この操作以降、上スクロールに関してのみ、メニューバーがスクロールされて画面上部に消えてしまい、top:0 の位置に固定されなくなるようにみえる現象が継続します。


原因と思われること

デバッグ用に表示した数値をみる限り、「7. ピンチイン」の段階で window.innerHeight と window.visualViewport.height の明確な差が確認できます。ただし、その後の検証により、この差はピンチイン操作によって発生したものではなく、input タグへのフォーカス時点ですでに発生していることが分かりました。

window.innerHeight と window.visualViewport.height は、

  • window.innerHeight

ブラウザが JavaScript に提供している、レイアウト上の viewport の高さに近い値。

  • visualViewport.height

ユーザーが実際に見ている、Visual Viewport の高さ。

を示します。

つまり、この違いにより、実際の画面の高さと JavaScript から取得できる viewport の状態に不整合が生じ、その結果、先頭固定のメニューバーの表示位置にも異常が発生しているようです。

WebKit 内部の viewport 処理に何らかの不整合が生じている可能性が高いと考えられます。

その後、さらに細かく検証したところ、<input> タグにフォーカスした時点で、すでにこの不整合が発生していることが確認できました。

文字を入力する必要はなく、フォーカスするだけで発生します。また、ソフトキーボードを閉じても状態は復旧しません。

一方、<input type="date"> ではこの現象は発生せず、ピンチイン・ピンチアウトだけを行っても発生しません。

このことから、単純なズーム処理ではなく、iOS 26 が通常の入力欄にフォーカスした際に行う、キーボードや Visual Viewport に関する処理が、この現象に関係している可能性が高いと考えています。

現時点では、WebKit 内部のどの処理によって不整合が発生しているのかまでは特定できません。しかし、<input> タグへのフォーカスを契機として window.innerHeight と window.visualViewport.height の不整合が発生し、その状態がソフトキーボードを閉じても維持されることは確認できました。

また、この現象は Safari だけでなく、iPhone 版Chrome でも確認しています。iOS 版 Chrome も WebKit を使用していることから、このことも WebKit 側の問題である可能性を示す材料の一つと考えています。

実際に WebKit にも、iOS 26 において、入力欄へのフォーカスやソフトキーボードの表示・非表示を契機として、fixed や sticky 要素の位置がずれる類似の問題が報告されています。


対策と復旧方法

残念ながら、この問題に対して、当サイトではHTML・CSS・JavaScriptによる確実な回避策を見つけることができませんでした。

また、問題が発生した後は、ページをリロードしても状態は復旧しませんでした。

現在確認できている復旧方法は、以下の2つです。

  • 一度タブを閉じ、新しいタブで当サイトを開き直す
  • iPhone をスリープさせた後、再びロックを解除する

いずれの場合も、問題が発生していた状態から正常な状態に戻ることを確認しています。


お願い

本記事のサンプルプログラムは、iPhone でも動作しますが、iOS 26 では、入力欄にフォーカスした後にメニューバーの固定表示が正常に行われなくなる場合があります。

現時点では当サイト側で確実な回避方法を確認できていないため、iPhone をご利用の方には、この点をご承知の上でサンプルプログラムをご利用いただきますようお願いいたします。

もしこの現象が発生した場合は、「対策と復旧方法」に記載した方法で復旧することができます。