スクロールチェーンを防ぐための「overscroll-behavior: contain」を応用した方法をご紹介します。
名付けて「つっかえ棒式モーダル背景固定法」です。
ソースコードはこちら
https://github.com/gorimatyan/css-modal-nonscroll
目次
1.対象読者
2.モーダルの構成
3.つっかえ棒で簡単解決
4.まとめ
5.追記
1. 対象読者
2. モーダルの構成
/* index.html */
<main id="container">
<div class="modalWrapper">
<div class="modal">
<header>ヘッダー</header>
<p>今日も頑張ろう</p>
</div>
</div>
</main>
3. つっかえ棒で簡単解決
結論
手順
①つっかえ棒を設置する
modalの下にdiv要素を一つ書きます。
/* index.html */
<main id="container">
<div class="modalWrapper">
<div class="modal">
<header>ヘッダー</header>
<p>今日も頑張ろう</p>
</div>
+ <div class="nonScroll"></div>
</div>
</main>
このnonScrollとやらが図にある黄色の「つっかえ棒」です。
②CSSを書く
modalWrapperとnonScrollにCSSを設定するだけでモーダルの背景がスクロールされなくなります。
.modalWrapper {
display: flex;
overscroll-behavior: contain;
overflow-y: scroll;
}
.nonScroll {
height:calc(100vh + 1px) ;
width: 1px;
background-color: transparent;
}
なぜスクロールされなくなる?
まずモーダルと背景が二層 (z-index) になっていると考えてください。
モーダル全体を囲むmodalWrapperに「overscroll-behavior」と「overflow-y」を設定することで、手前にあるモーダル全体がスクロールの対象になります。
よって、モーダル全体(modalWrapper)に覆われている背景はスクロールされなくなるという理屈です。
まとめ
あなたの作っているモーダルに対して
①モーダルを構成する親要素に.modalWrapperのCSSを当てる
②その子要素にdiv.nonScrollを配置し上記のCSSを当てる
実際に見てみたいという方はワタクシのGitHub貼っときますので覗いちゃってください。
https://github.com/gorimatyan/css-modal-nonscroll
追記
Twitterにてatomsphere5様が改良したものを載せております!
改良前:HTMLにdiv.nonScrollを追加
→ 改良後:疑似クラスで作成することで完全にCSSのみで実装可能に
下記ツイートのリンクからコードサンドボックスでデモが見られるので是非ご確認ください!!
これは知らなかった
— わかるたくと@エンジニアが足りない (@atomsphere5) July 16, 2022
「CSSだけで」とあるので新規に.nonScrollを追加しないといけないの勿体無い気がしたので、前後に擬似クラスbefore、afterにて同じ思想で実装しなおしてみた。
モーダルの表示自体はJavascriptだが、本当に完全にやりたければcheckboxとforでも実装可https://t.co/JEDpeuafcw https://t.co/FQ1as7rhDN