0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

なぜiOS SafariだけUIが崩れるのか?viewportから理解するブラウザの違い

0
Posted at

はじめに

業務でフロントエンド開発をしている中で、
「iOSのSafariだけUIが崩れる」という問題に遭遇しました。

Chromeでは問題ないのに、iPhoneで見るとレイアウトが崩れる。

最初は「Safariのバグかな?」と思ったのですが、調べていくうちに、

そもそもSafariだけの問題ではなく、vh と viewport のズレが原因

であることに気づきました。

この記事では、特定の解決方法ではなく、

  • なぜSafariで崩れて見えるのか?
  • viewportとは何か?
  • なぜ 100vh でズレが起きるのか?

といった背景理解にフォーカスしてまとめます!

viewportとは?

viewportとは「画面に表示される領域」のことです。

例えば、同じWebページでも、

  • PCで見る場合 → 大きな画面いっぱいに表示される
  • スマホで見る場合 → 小さい画面に合わせて縮小・再配置される

このとき、「どの範囲を画面として扱うか」を決めているのがviewportです。

なぜ100vhでズレが起きるのか?

height: 100vh;

通常、vh は「viewportの高さの1%」ですが、
この「viewport」の扱いはブラウザによって異なります。

例えば、

  • アドレスバーが表示されているとき
  • スクロールしてバーが隠れたとき
  • 入力キーボードが表示されたとき

といった状態によって、表示領域の高さは変わります。
これはモバイルブラウザとしては自然な挙動です。
Safariが特徴的なのは、vh がこの変化に追従せず、ページ読み込み時の最大の高さで固定されてしまうことです。
そのため、「実際に見えている高さ」と「vhで計算された高さ」がズレるという現象が起きます。
結果として、

  • 下に余白ができる
  • 要素がはみ出る
  • スクロールでズレる

といった現象が起きます。

もっとわかりやすくいうと

例えば、あなたのiphoneの画面の高さが20cmだとしましょう。

初期状態(アドレスバーあり)

  • 画面全体:20cm
  • アドレスバー:1cm
  • 実際に見えている領域:19cm

このとき、ユーザーが見ているのは19cmですが、
100vh は20cmとして計算されることがあります。

キーボードが表示された場合

  • キーボード:4cm
  • アドレスバー:1cm
  • 実際に見える領域:15cm
  • ですが、100vhは20cm のまま

この結果、

  • フッターが画面の外にいく
  • ボタンがキーボードに隠れる

といった問題が発生します。

つまり、

「実際に見えている高さ」と「vhで計算された高さ」がズレること

これがレイアウト崩れの原因です。

なぜ一筋縄で解決しないのか?

100dvh を使って動的にviewportが追従するようにすれば解決するケースもありますが、

実際のアプリでは、

  • 他のレイアウトとの兼ね合い
  • fixed / flex / scroll の組み合わせ
  • JavaScriptによる制御

などが絡み合っているため、
単純に単位を変えるだけでは解決しないことも多いです。

dvh はCSS仕様に正式追加された比較的新しい単位で、svh(UIバー表示時の高さ)・lvh(UIバー非表示時の高さ)・dvh(動的に変化)の3種類があります。

おわりに

同じようにSafariでハマってモヤモヤした人の参考になれば嬉しいです。

0
1
0

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
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?