iPhoneXが発売されしばらくたち、iOS11のリリースやバグで世間は賑わっているようです。
iPhoneXで新しく導入されたSafe Areaにコンテンツがどのように表示されるのか、ざっと検証してみました。
今回検証したポイント
- 固定フッター(スマホサイトでよく見られるページ下部にメニューなどがfixedで固定されているデザイン)がどのような見え方になるのか
- iOS11.1とiOS11.2の記述方法の違い
関連ワード
Safe Area
, viewport
, css
, constant()
, env()
検証に利用した基本コード・修正前(一部を抜粋)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>iPhoneX対応</title>
<style>
body {
margin: 0;
background-color: #f3fcfe;
}
p {
margin: 0;
}
.bottom {
position: fixed;
bottom: 0;
left: 0;
right: 0;
width: 100%;
background-color: #00c2fa;
height: 35px;
}
.bottom .inner{
width: 100%;
}
</style>
</head>
<body>
<div class="bottom">
<div class="inner">めにゅう</div>
</div>
<div class="contents">
<p style="font-size: 20px;font-weight: bold;">夏目漱石「私の個人主義」</p>
<p>我々も今日よほど同じ意味帰りというのの所に読みたいた。<br>・・・・</p>
</div>
</body>
</html>
Safe Area対応を何もしない場合
固定フッターがないページ
固定フッターさえなければ、何も対応せずとも特に問題なさそうです。
[ポートレート]
固定フッターがあるページ
ポートレート・ランドスケープともに、スクロールをした時に固定フッターがSafe Areaに侵入してしまいます。
ホームバーが固定フッターに被っているため、固定フッター内のリンクなどをタップしようとすると、最初にホームバーが反応してiPhoneの下部メニューが開き、再度リンクをタップするとリンクが反応します。
要するに、2度タップしないとリンクしないので、ユーザーとしては非常に使いにくいです。
[ポートレート]
ロードした時は特に問題ないのですが、下にスクロールし始めると固定フッターがSafe Areaに侵入し、ホームバーに完全に被ってしまいます。
[ランドスケープ]
ロードした時そもそも固定フッターが表示されていません。
スクロールし始めると固定フッターが表示されますが、 Safe Areaに固定フッターが侵入し、ホームバーに被ってしまいます(キャプチャはうまく撮れませんでしたが、、)。
viewportだけを指定した場合
iPhoneXのSafe Areaに対応するために新しいviewportが登場しました。
viewport-fit=cover
というところです。
CSSを何もいじらず、viewportだけを変えると、全体的に悲しい感じになります(特にランドスケープ)。
既存サイトを修正する場合は、間違っても更新したhtmlが先にリリースされないように注意が必要です。
<meta name='viewport' content='initial-scale=1, viewport-fit=cover’>
viewportを指定してconstant()を指定した場合
constant(safe-area-inset-top)
、constant(safe-area-inset-left)
、constant(safe-area-inset-right)
、constant(safe-area-inset-bottom)
という新しい値を利用して、Safe Areaにコンテンツが侵入しないように、paddingやmarginを入れることができます。
こちらの対応をしている記事を結構多く見るかなという印象です。
iOS11.2がリリースされるまではこれで大丈夫だったのですが、iOS11.2で突然constant()を廃し、env()を採用するようになったようなので、iOS11.2にアップデートした端末ではせっかくやった対応が水の泡と化します。
.bottom {
padding-bottom: constant(safe-area-inset-bottom);
}
.contents{
padding-right: constant(safe-area-inset-left);
padding-left: constant(safe-area-inset-left);
}
viewportを指定してenv()を指定した場合
今後はenv()を使っていくとWebKitの技術ブログにも記載があるので、env()を試してみます。
env(safe-area-inset-top)
、env(safe-area-inset-left)
、env(safe-area-inset-right)
、env(safe-area-inset-bottom)
が値として使えます。
iOS11.2では想定通りの表示となりましたが、残念ながら、iOS11.1以下には効かないようです。
.bottom {
padding-bottom: env(safe-area-inset-bottom);
}
.contents{
padding-right: env(safe-area-inset-left);
padding-left: env(safe-area-inset-left);
}
viewportを指定してconstant()とenv()の両方を指定した場合
全てのiPhoneXに対応しようとすると、constant()とenv()両方指定する必要があるようです。
両方指定した場合は、サポートしていない値はさらっと無視するだけなので、両方指定してあれば当面問題なさそうです。
ただし、iOS11.1は多くのバグを含んだバージョンだったようなので、いつまでも両方サポートしてあげる必要はない可能性が高そうです。
検証に利用した基本コード・修正後(一部抜粋)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>iPhoneX対応</title>
<style>
body {
margin: 0;
background-color: #f3fcfe;
}
p {
margin: 0;
}
.bottom {
position: fixed;
bottom: 0;
left: 0;
right: 0;
width: 100%;
background-color: #00c2fa;
height: 35px;
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
.bottom .inner{
width: 100%;
}
.contents{
padding-right: constant(safe-area-inset-right);
padding-left: constant(safe-area-inset-left);
padding-right: env(safe-area-inset-right);
padding-left: env(safe-area-inset-left);
}
</style>
</head>
<body>
<div class="bottom">
<div class="inner">めにゅう</div>
</div>
<div class="contents">
<p style="font-size: 20px;font-weight: bold;">夏目漱石「私の個人主義」</p>
<p>我々も今日よほど同じ意味帰りというのの所に読みたいた。<br>・・・・</p>
</div>
</body>
</html>
参考サイト