iosでモーダルの高さ100vhがいい感じに反応してくれない
iosでモーダルの高さを100vh
にしたときに下のコンテンツが上手く表示されなかったので、そのときの対応したことのメモ
jsでの高さ取得については今回は省略します。
実際にどんな状態か
See the Pen modal-viewport-ng by miwa_shuntaro (@miwashutaro0611) on CodePen.
現状行っているコードについて
仕様のマークアップ
上のコードは一部タグ省略。
<button type='button'>モーダルが開く</button><!-- モダールを開くためのボタン --> <div class='modal'> <div class='modal--header'> <!-- 上の固定部分 --> <button type='button'>モーダルが閉じる</button> </div> <form class='modal__inner'> <div class='modal__inner--content'><!-- スクロールする部分 --> <input type='text' value='' /> <!-- ここからいろいろ続く --> </div> <div class='modal__inner--footer'> <!-- 下の固定部分 --> <button type='submit'>フォームの内容送信</button> </div> </form> </div>
.modal
モーダル全体の大枠を作成
- 通常時
.modal { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 10; display: none; background-color: rgba(0, 0, 0, 0.5); }
- モーダルが出現したら
.modal.is-open { display: block; opacity: 1; pointer-events: auto; }
.modal--header
モーダルが出現した時の上部分
.modal--header { position: absolute; top: 0; right: 0; left: 0; z-index: 11; margin: 0; height: 56px; background-color: #f00; }
.modal__inner--content
実際に要素がスクロールする部分
.modal__inner--content { overflow-y: scroll; box-sizing: border-box; padding: 56px 0 60px; height: 100vh; -webkit-overflow-scrolling: touch; }
.modal__inner--content__text
.modal__inner--content__text > p
高さを100vh以上いくための仮埋めなので、省略。
.modal__inner--footer
モーダルが出現した時の下部分
.class { position: fixed; right: 0; bottom: 0; left: 0; z-index: 11; padding: 4px 12px; height: 60px; background-color: #0ff; box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.2); }
解決方法
See the Pen modal-viewport-ok by miwa_shuntaro (@miwashutaro0611) on CodePen.
現状行っているコードについて
<button type='button'>モーダルが開く</button><!-- モダールを開くためのボタン --> <div class='modal'> <div class='modal--header'> <!-- 上の固定部分 --> <button type='button'>モーダルが閉じる</button> </div> <form class='modal__inner'><!-- スクロールする部分をここに変更 --> <div class='modal__inner--content'> <input type='text' value='' /> <!-- ここからいろいろ続く --> </div> <div class='modal__inner--footer'> <!-- 下の固定部分 --> <button type='submit'>フォームの内容送信</button> </div> </form> </div>
.modal
.modal { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 10; display: none; height: 100%; /* 親要素の高さを取得する */ background-color: rgba(0, 0, 0, 0.5); }
.modal--header
変更なし
.modal__inner
.modal__inner { overflow-y: auto; box-sizing: border-box; margin-top: 56px; /* header分marginを空ける */ height: calc(100% - 60px - 56px); /* 100% - header分の高さ - footer分の高さ */ -webkit-overflow-scrolling: touch; }
.modal__inner--content
ここにあった既存の要素は削除
.modal__inner--footer
変更なし
補足
スクロールエリアを.modal__inner
ではなく、.modal__inner--content
のままにした場合は
.modal__inner
.modal__inner { height: 100%; }
.modal__inner--content
.modal__inner--content { overflow-y: auto; box-sizing: border-box; margin-top: 56px; /* header分marginを空ける */ height: calc(100% - 60px - 56px); /* 100% - header分の高さ - footer分の高さ */ -webkit-overflow-scrolling: touch; }
のように対応すればできる。
なぜ起こるのか
height: 100%
と height: 100vh
の違い
100% を指定した場合 要素の縦幅は画面の縦幅からアドレスバーを差し引いた高さとなります。
100vh を指定した場合 要素の縦幅は画面の縦幅と同じ高さになります。
によって取得できる高さが違うため。
https://hysryt.com/archives/1092 より画像・テキストを引用
また、包含ブロックに対して height: 100%
を宣言すれば height: 100%
で高さを取得することができるため、今回は height: 100%
で対応。
https://w3g.jp/css/guide/contining_block より参考