当目标元素不溢出时 CSS `overscroll-behavior: contains`

ben*_*neb 20 css overflow overscroll

"overscroll-behavior: contain"我正在寻找一个 CSS 解决方案来实现但目标元素没有溢出时的确切行为。

我有一个带有弹出侧边栏/菜单的页面,在移动设备上,该页面占用 100vw 和 100vh(减去底部导航栏)并且不会溢出(没有足够的内容需要滚动条)。目前,当此侧边栏在移动设备上打开时,如果用户尝试滚动它,后台的主页面会滚动,在此应用程序中,由于延迟加载/无限滚动,这可能会导致不必要的数据库调用。

这是一个最小的codesandbox演示

编辑连续的 Material-UI Snackbars

在 demo.js 的第 55 行,我已将overscrollBehavior: "contain"属性添加到 JSS 中,但是正如您所看到的,它不包含滚动链,除非您缩小浏览器的垂直高度以强制侧边栏的内容先溢出。(在 Chrome 上,overscrollBehaviorcodesandbox 编辑器中似乎有预期的行为,但在它自己的窗口中弹出时却没有。)

当然有一个 CSS 解决方案可以实现这种行为,无需先让元素可滚动吗?

有趣的是,至少在 Firefox 上,如果您缩小垂直高度以强制在侧边栏上滚动,一旦您将浏览器大小调整回正常状态,该overscroll-behavior属性将继续包含滚动链,直到您刷新页面,这就是我的行为正在寻找,尽管显然是在初始页面加载时。

这是一个简单的代码笔,overscroll-behavior显示了溢出和不溢出的元素之间的差异(如果还不清楚的话)。我还在2018 年的CSS Tricks 论坛上发现了另一篇帖子,其中有人询问此行为,但没有解决方案。

小智 1

既然函数式:has()伪类得到了大约 90% 的用户的相对良好的支持,我们可以使用它创建一些类似的功能。

注意:在您的 codepen 示例中,我给了第二个<p>.scrollContain以便于选择。

body:has(.scrollContain:hover) {
  overflow-y: hidden;
}
Run Code Online (Sandbox Code Playgroud)

这里发生了什么事?

  • body:has(.scrollContain:hover):选择 body 元素,但前提是它有一个.scrollContain正在悬停的 class 子元素。(注意:您可以替换body为任何其他不应滚动的元素)
  • overflow-y: hidden为了禁用body元素上的滚动

功能并非 100% 相同,因为外部元素滚动完全禁用,因此滚动条将消失。但卷轴本身的行为是相同的。一旦过度滚动内部元素(因此将鼠标悬停在其上),外部元素将不会滚动。

附加说明:position: fixed与 一起使用overflow: scroll也会禁用滚动,同时强制滚动条仍然显示(尽管已禁用)。但在大多数情况下,body由于它已从正常页面流中删除,因此会跳转。但这在外部容器已经固定在给定top位置的某些情况下可能有效。


body:has(.scrollContain:hover) {
  overflow-y: hidden;
}
Run Code Online (Sandbox Code Playgroud)
body:has(.scrollContain:hover) {
  overflow-y: hidden;
}

p {
  height: 180px;
  width: 100px;
  overflow: scroll;
  margin: 20px;
}

p:nth-child(2) {
  overscroll-behavior: contain;
}

body {
  display: flex;
  padding: 20px;
  min-height: 200vh;
}
Run Code Online (Sandbox Code Playgroud)