deezus blog

.Net Core、Typescriptを中心に技術的ノウハウを公開しています

IOSではbodyにoverflow:hiddenが効きません

はじめに

現在開発中のSPAのWebシステムでは画面外にトーストのようなdivを配置し、メッセージを表示する際には座標を移動させ、画面に表示されるようにしています
Androidでは問題なく動作しますが、iPadで動作確認した際、画面外のトーストが表示されてしまいました
原因はbodyにoverflow:hiddenを指定し、スクロールできないようにしていたのですが、IOSでは無視されるようです

HTML

ボタンをクリックするとトーストが表示されます

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>トースト</title>
<style>
body, html{
    height: 100%;
    overflow: hidden;
    margin: 0;
}
.content{
    height: 100%;
}
#toast{
    position: absolute;
    width: 100%;
    height: 50px;
    bottom: -50px;
    transition: bottom .2s;
}

#toast p{
    background: rgba(0, 0, 0, 0.5);
    line-height: 30px;
    color: #fff;
    margin: 10px;
    text-align: center;
}

#toast.show{
    bottom: 0px;
}
</style>
</head>
<body>
<div class="content">
    <button id="showButton">toast表示</button>
</div>
<div id="toast">
<p>通知内容</p>
</div>
<script>
<!--
document.getElementById('showButton').addEventListener('click', function(e){
    var toast = document.getElementById('toast');
    toast.className = 'show';
});
-->
</script>
</body>
</html>

ところが、IOSの場合bodyに指定したoverflow: hiddenが効かず、スクロールできてしまい、画面外に隠している#toastが見えてしまいます

対策

  1. #toastをbody直下ではなく.contentの中に移動させる
  2. .contentにposition: relative, overflow: hiddenを指定する
  3. bodyのoverflowを削除する
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>トースト</title>
<style>
body, html{
    height: 100%;
    margin: 0;
}
.content{
    height: 100%;
    overflow: hidden;
    position: relative;
}
#toast{
    position: absolute;
    width: 100%;
    height: 50px;
    bottom: -50px;
    transition: bottom .2s;
}

#toast p{
    background: rgba(0, 0, 0, 0.5);
    line-height: 30px;
    color: #fff;
    margin: 10px;
    text-align: center;
}

#toast.show{
    bottom: 0px;
}
</style>
</head>
<body>
<div class="content">
    <button id="showButton">toast表示</button>
    <div id="toast">
        <p>通知内容</p>
    </div>
</div>

<script>
<!--
document.getElementById('showButton').addEventListener('click', function(e){
    var toast = document.getElementById('toast');
    toast.className = 'show';
});
-->
</script>
</body>
</html>

まとめ

スクロールをできないようにする必要がある場合は、bodyの直下に1つdivを作り、それに対してoverflow: hiddenを指定すればIOSでもスクロールできなくなります