理論
pinterestサイトの現在の実装(将来変更される可能性があります)を見ると、オーバーレイを開くと、noscroll
クラスがbody
要素に適用されてoverflow: hidden
設定されているため、body
スクロールできなくなります。
オーバーレイ(オンザフライまたはすでにページ内の作成を介して見えるようになるdisplay: block
、それは違いはありませんが、)ありposition : fixed
とoverflow-y: scroll
、とtop
、left
、right
およびbottom
に設定されたプロパティ0
:このスタイルは、全体のビューポートを埋めオーバーレイます。
div
オーバーレイの内側は、代わりにposition: static
、表示される垂直スクロールバーがその要素に関連しています。その結果、コンテンツはスクロール可能ですが、オーバーレイは固定されたままです。
ズームを閉じると、オーバーレイが(を介してdisplay: none
)非表示になり、JavaScriptを介して完全に削除することもできます(または、内部のコンテンツだけを挿入する方法は、あなた次第です)。
最後のステップとして、noscroll
クラスも削除する必要がありますbody
(そのため、overflowプロパティは初期値に戻ります)。
コード
コードペンの例
(aria-hidden
オーバーレイの表示と非表示、およびアクセシビリティを高めるためにオーバーレイの属性を変更することで機能します)。
マークアップ
(開くボタン)
<button type="button" class="open-overlay">OPEN LAYER</button>
(オーバーレイして閉じるボタン)
<section class="overlay" aria-hidden="true">
<div>
<h2>Hello, I'm the overlayer</h2>
...
<button type="button" class="close-overlay">CLOSE LAYER</button>
</div>
</section>
CSS
.noscroll {
overflow: hidden;
}
.overlay {
position: fixed;
overflow-y: scroll;
top: 0; right: 0; bottom: 0; left: 0; }
[aria-hidden="true"] { display: none; }
[aria-hidden="false"] { display: block; }
Javascript (バニラ-JS)
var body = document.body,
overlay = document.querySelector('.overlay'),
overlayBtts = document.querySelectorAll('button[class$="overlay"]');
[].forEach.call(overlayBtts, function(btt) {
btt.addEventListener('click', function() {
/* Detect the button class name */
var overlayOpen = this.className === 'open-overlay';
/* Toggle the aria-hidden state on the overlay and the
no-scroll class on the body */
overlay.setAttribute('aria-hidden', !overlayOpen);
body.classList.toggle('noscroll', overlayOpen);
/* On some mobile browser when the overlay was previously
opened and scrolled, if you open it again it doesn't
reset its scrollTop property */
overlay.scrollTop = 0;
}, false);
});
最後transition
に、opacity
プロパティに適用されたCSSによるフェードイン効果でオーバーレイが開く別の例を次に示します。またpadding-right
、スクロールバーが消えたときに下にあるテキストのリフローを回避するために適用されます。
コードペンの例(フェード)
CSS
.noscroll { overflow: hidden; }
@media (min-device-width: 1025px) {
/* not strictly necessary, just an experiment for
this specific example and couldn't be necessary
at all on some browser */
.noscroll {
padding-right: 15px;
}
}
.overlay {
position: fixed;
overflow-y: scroll;
top: 0; left: 0; right: 0; bottom: 0;
}
[aria-hidden="true"] {
transition: opacity 1s, z-index 0s 1s;
width: 100vw;
z-index: -1;
opacity: 0;
}
[aria-hidden="false"] {
transition: opacity 1s;
width: 100%;
z-index: 1;
opacity: 1;
}