iOSのSafari(およびiOS版Chromeなど、WebKitベースのブラウザ)でscrollIntoView({ behavior: "smooth" })
が期待通りに動作しないというバグがあります。Androidやデスクトップでは問題なく動作するのに、iOSでだけ挙動がおかしいという状況です。
原因
-
描画のタイミング: iOSにおけるパフォーマンス最適化のため、JavaScriptの実行とDOMの描画を厳密に制御することがあります。スクロール命令が出た際に、DOMの状態がまだ完全に更新されていなかったり、他のレイアウト処理が走っていたりすると、スクロールが正確に行われないことがあります。
-
WebKitの仕組み: WebKit(Safariが使用しているブラウザエンジン)の
scrollIntoView
の実装が、他のブラウザ(ChromiumやGecko)と完全に一致しないケースがあります。特に過去のバージョンではbehavior
オプションのサポートが不完全でした。
解決策
1、 setTimeout
を使った遅延
これは最も手軽な方法で、スクロールした後、DOMを安定させる前に短い時間(例: 50ms〜200ms)の遅延を設けることです。ただし、ネットワークの遅延によりある要素がちらついてしまう可能性があります。
setTimeout(() => {
titleRef.current?.scrollIntoView({ behavior: 'smooth' });
}, 100);
2、 behavior: 'auto'
にする
behavior: 'smooth'
の使用を避けることは最も安全な解決策ですが、スクロールが瞬時に行われるため、スムーズなアニメーション演出は無くなります。
setTimeout(() => {
titleRef.current?.scrollIntoView(); // ({ behavior: 'auto' })と同等
}, 100);
3、 smoothscroll-polyfill
の使用
iOSの古いバージョンなど、ネイティブのscrollIntoView
の互換性が低い環境に対応するために、ポリフィルを導入するのが最も堅牢な方法です。多くのサイトで安定して動作することが確認されています。