问题描述
查看 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
(因此溢出属性返回到其初始值)
(它通过改变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>
.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; }
(原版 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 以避免底层文本重排。
.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;
}
解决方法
我一直在寻找一种“灯箱”类型的解决方案,它允许这样做,但还没有找到(如果你知道的话,请提出建议)。
我试图重现的行为就像你在Pinterest点击图片时看到的一样。叠加层是可滚动的(
因为整个叠加层像页面顶部的页面一样向上移动)但叠加层 后面 的主体是固定的。
我试图只用 CSS 来创建它( 即div
覆盖在整个页面和正文的顶部overflow: hidden
),但它不会阻止div
可滚动。
如何保持正文/页面不滚动但继续在全屏容器内滚动?