我一直在寻找一种“灯箱”类型的解决方案,它允许这样做,但还没有找到(如果你知道的话,请提出建议)。
我试图重现的行为就像你在Pinterest点击图片时看到的一样。叠加层是可滚动的( 因为整个叠加层像页面顶部的页面一样向上移动)但叠加层 后面 的主体是固定的。
我试图只用 CSS 来创建它( 即div覆盖在整个页面和正文的顶部overflow: hidden),但它不会阻止div可滚动。
div
overflow: hidden
如何保持正文/页面不滚动但继续在全屏容器内滚动?
理论
查看 pinterest 站点的当前实现(将来可能会更改),当您打开叠加层时,一个noscroll类将应用于body元素并overflow: hidden设置,因此body不再可滚动。
noscroll
body
叠加层(即时创建或已在页面内创建并通过 显示,display: block没有区别)具有position : fixed和overflow-y: scroll、top、left和属性设置为:此样式使叠加层填充整个视口。right``bottom``0
display: block
position : fixed
overflow-y: scroll
top
left
right``bottom``0
覆盖的div内部只是在position: static您看到的垂直滚动条与该元素相关。结果,内容是可滚动的,但覆盖仍然是固定的。
position: static
当您关闭缩放时,您会隐藏叠加层(通过display: none),然后您也可以通过 javascript 完全删除它(或者只是里面的内容,如何注入它取决于您)。
display: none
作为最后一步,您还必须将noscroll类删除body(因此溢出属性返回到其初始值)
代码
代码笔示例
(它通过改变aria-hidden覆盖层的属性来显示和隐藏它并增加它的可访问性)。
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应用 a 以避免底层文本重排。
transition
opacity
padding- right
Codepen 示例(淡入淡出)
.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; }