防止主体滚动但允许覆盖滚动

2024-06-22

我一直在寻找一种“灯箱”类型的解决方案来实现这一点,但尚未找到(如果您知道的话,请提出建议)。

我试图重现的行为就像你看到的那样兴趣 http://www.pinterest.com单击图像时。覆盖层是可滚动的(就像整个覆盖层向上移动一样,就像一个页面叠在一个页面上一样)但是身体behind覆盖层是固定的。

我尝试仅使用 CSS 创建它(i.e. a div覆盖在整个页面和正文的顶部overflow: hidden),但这并不能阻止div从可滚动。

如何防止正文/页面滚动但在全屏容器内保持滚动?


Theory

查看 pinterest 网站的当前实现(将来可能会改变),当您打开覆盖层时,会出现一个noscroll类应用于body元素(设置overflow: hidden)使body不再可滚动。

动态创建的覆盖层或已注入页面并通过以下方式可见display: block没什么区别 – has position : fixed and overflow-y: scroll, with top, left, right and bottom属性设置为0:这种样式使叠加层填充整个视口(但现在我们已经是 2022 年了,所以你可以使用inset: 0反而)。

The div覆盖层里面是position: static所以垂直滚动条与该元素相关。这导致了可滚动但固定的覆盖。

当你关闭覆盖层时,你必须隐藏它(使用display: none),您甚至可以通过 javascript 删除节点(或仅删除其中的内容,这取决于您,但也取决于内容的性质)。

最后一步也是删除noscroll类应用于body(所以overflow财产恢复到之前的价值)


Code

Codepen 示例 https://codepen.io/fcalderan/pen/qBYyRgE?editors=0010

(它的工作原理是改变aria-hidden覆盖层的属性,以便显示和隐藏它并增加其可访问性)。

Markup
(打开按钮)

<button type="button" class="open-overlay">OPEN LAYER</button>

(覆盖和关闭按钮)

<section class="overlay" aria-hidden="true" tabindex="-1">
  <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;
   inset: 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"]'),
    openingBtt;
    
[].forEach.call(overlayBtts, function(btt) {

  btt.addEventListener('click', function() { 
     
     /* Detect the button class name */
     var overlayOpen = this.className === 'open-overlay';
     
     /* storing a reference to the opening button */
     if (overlayOpen) {
        openingBtt = this;
     }
     
     /* 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;
     
      /* forcing focus for Assistive technologies but note:
    - if your modal has just a phrase and a button move the
      focus on the button
    - if your modal has a long text inside (e.g. a privacy
      policy) move the focus on the first heading inside 
      the modal
    - otherwise just focus the modal.

    When you close the overlay restore the focus on the 
    button that opened the modal.
    */
    if (overlayOpen) {
       overlay.focus();
    }
    else {
       openingBtt.focus();
       openingBtt = null;
    }

  }, false);

});

/* detect Escape key when the overlay is open */
document.body.addEventListener('keyup', (ev) => {
   if (ev.key === "Escape" && overlay.getAttribute('aria-hidden') === 'false') {
      overlay.setAttribute('aria-hidden', 'true');
      body.classList.toggle('noscroll', false);
      openingBtt.focus();
      openingBtt = null;
   }
})

最后,这是另一个示例,其中叠加层通过 CSS 打开并具有淡入效果transition应用于opacity财产。也padding-right用于避免滚动条消失时底层文本的重排。

Codepen 示例(淡入淡出) https://codepen.io/fcalderan/pen/mdLjRYW?editors=0110

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;
     inset: 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; 
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

防止主体滚动但允许覆盖滚动 的相关文章

  • 有选择地格式化 PowerShell 管道中的数据并输出为 HTML 的技术

    假设您想要对 powershell 的某些表格输出进行一些奇特的格式化 并且目标是 html 用于网络服务器 或者通过电子邮件发送 举例来说 您希望某些数值具有不同的背景颜色 任何 我可以想到两种可靠的编程方法来实现此目的 输出 XML 并
  • 跨多行标记时如何避免空格

    朋友们 我在用着atom编写html代码 每次我输入 p 这个词 它都会自动生成3行代码 p p 现在我给出一个内联类 将两个 p 元素放在一行中 inline display inline block p class inline Hi
  • 导出时的 Highcharts css 样式

    I have the following graph in digital See image but when using the Highchart s hamburguer CSS menu to export to PDF or J
  • 匿名行内框是否包含空格?

    我阅读了 CSS2 1 规范 并在 匿名内嵌框 https www w3 org TR CSS22 visuren html anonymous部分 它显示了一个匿名内联框的示例 如下所示 p Some em emphasized em t
  • 根据输入字段的字符数动态扩展输入类型“文本”的高度

    与下面的 JSFiddle 类似 我将其添加为书签 但不知道原始问题从哪里出现 http jsfiddle net mJMpw 6 http jsfiddle net mJMpw 6
  • 检测 div 何时溢出

    我试图让我的网站根据屏幕的大小流动 我创建了这个 http jsfiddle net aboveyou00 7NeZz 1 http jsfiddle net aboveyou00 7NeZz 1 它运行得很好 当两个内部 div 适合时
  • 使内联块在溢出时缩小到内容

    I have an inline block container with several other inline block elements like so The container is the blue background t
  • Angular Component CSS 封装是如何工作的?

    我想了解如果我创建两个样式表 Style 1 heading color green Style 2 heading color blue 现在如果这两种样式写在两个不同的视图中 渲染它们的时候 在布局上作为局部视图 https jakey
  • Angular 5 材质小吃栏

    我遇到的问题是 小吃栏组件在初始化时附加在 cdk global overlay wrapper 外部 位于 cdk overlay container 内 这使得它在屏幕中间瞬间可见 然后它消失并重新附加到 cdk global over
  • CSS 向后/反向过渡

    我想知道是否有任何方法可以使用相同的 CSS 过渡实例来向前移动然后向后 反向移动 例如 假设我有这样的转变 webkit keyframes fade transition from opacity 0 to opacity 1 以及这次
  • 适用于所有浏览器的 Center HTML 5 音频播放器

    我尝试过这样的代码 div style margin 0 auto div
  • 子 div 超出父 div 范围

    目前我正在使用 CSS 和 HTML 等设计一个网站 但是我遇到了一个问题 当我向子级添加浮动时 我的子级 div 超出了父级 div 的范围 该网站位于此处我的网页设计 http 7sisters in test mintbite 更加详
  • 带有 selectInputs 的 DT 数据表在选择后重置回左侧

    我在 Shiny 应用程序的 DT 数据表的列中使用 selectInputs 感谢一些帮助here https stackoverflow com questions 74620665 vertically center selectin
  • 在画布中心写入 (0,0)-HTML5

    I m currently developing a drawing app which allows the user to click and drag to determine the size of the shape and al
  • CSS @import 及其顺序

    是否可以使用 importone像这样的 css 文件 import file1 some css here import file2 chrome 无法识别上述第二个导入 但这可以工作 import file1 import file2
  • 将jQueryUI datepicker附加到div(显示位置错误)

    我在输入上使用 jQueryUI datepicker 默认情况下 jQueryUI 会附加 ui datepicker div to the body该文件的 有问题的输入位于屏幕上的 弹出 div 中 这意味着该 div 之外的任何点击
  • JQuery mouseover 函数多次触发

    我很长时间以来一直使用这种方法来为整个类 按钮等 设置事件 div bigButton mouseover function this style backgroundColor dfdfdf 然而 在进行一些测试时 我刚刚注意到 当将鼠标
  • Bootstrap 面板主体,内有表格

    我有一个引导面板 单击图标即可折叠并自动关闭 该面板内部包含一个全宽的表格 但只有在没有任何内容时才看起来像这样panel body 例如 这张桌子横跨面板的整个宽度和高度 看起来不错 但如果我可以有一个围绕桌子的类 我会更喜欢 但是 如果
  • CSS 链接图像带有下划线(“a”显示设置为阻止)

    我有一个菜单 我希望每个单独的项目中文本周围的所有空间都能将用户带到指定的页面 我在网上查了一下 发现最好的解决方案是将 a 显示设置为阻止 如下 a display block height 100 text decoration und
  • 如何在流体宽度表中使用省略号而不使每列大小相同?

    假设我的表中的列是id name description and phone The description列的长度为 1 255 个字符 但 id 最多只有 3 个字符 我希望列的大小适当 而不是每列的大小相同 我想要descriptio

随机推荐