jackmiwamiwa devblog

フロントエンドをメインに行ったことをまとめていくサイトになります。

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 を指定した場合 要素の縦幅は画面の縦幅と同じ高さになります。

によって取得できる高さが違うため。

height_eye.png (22.9 kB)

https://hysryt.com/archives/1092 より画像・テキストを引用

また、包含ブロックに対して height: 100%を宣言すれば height: 100%で高さを取得することができるため、今回は height: 100% で対応。

https://w3g.jp/css/guide/contining_block より参考

その他参考リンク