禁用页面滚动

271

我想完全禁用HTML body的滚动。 我已尝试以下选项:

  • overflow: hidden;(不起作用,无法禁用滚动,它只隐藏了滚动条)

  • position: fixed;(这个可以工作,但它会完全滚动到顶部,对于此特定应用程序是不可接受的)

我找不到这两个选项之外的任何替代方案,还有其他方法吗?


3
你应用了哪个元素的overflow:hidden属性? - Sajad Karuthedath
你在这里究竟想要实现什么?你的最终目标是什么? - jbutler483
2
展示相关的代码将会更容易帮助您。 - Sleek Geek
1
overflow: hidden; 是解决问题的方法。如果它不起作用,那么你的 CSS 中可能存在其他问题。尝试使用 html、body {overflow: hidden;},如果这仍然无效,请尝试 * {overflow: hidden;} 并找出问题所在。 - Jonas Grumann
请在<body>中使用height: 100%; overflow: hidden样式。 :) - mehmet
12个回答

438

5
忘记在"body"前面加上 "html"。 - user4532193
6
如果您在iOS上有一个固定位置的叠加元素,可能导致页面无法正常工作。 - notQ
2
你可以添加"overflow":"hidden",这样它就能正常工作了。 - JPG
3
有时您可能更喜欢使用height: 100vh ; ) - neox5
1
@neox5 你可能想要了解100dvh或其他较新的变体--有关此错误的更多信息在这里:https://nicolas-hoizey.com/articles/2015/02/18/viewport-height-is-taller-than-the-visible-part-of-the-document-in-some-mobile-browsers/ - Swivel
显示剩余2条评论

25
为了实现这一点,在 <body> 元素上添加2个CSS属性。
body {
   height: 100%;
   overflow-y: hidden;
}

现在有许多新闻网站要求用户创建帐户。通常他们会给予完整的页面访问权限约一秒钟,然后显示弹出窗口,并停止用户向下滚动。

The Telegraph

编辑

此外,一些网站(例如Quora)还会使部分文本模糊不清。一般情况下,他们会通过应用以下CSS来实现此目的。

filter: blur(3px);

这会隐藏滚动条。然而,问题特别要求寻找隐藏滚动条的替代方法。 - DataGeek
2
@DataGeek,这不仅隐藏了滚动条,还停止了向下滚动的能力。而且我理解这就是所要求的。即不仅隐藏它,还使向下滚动变得不可能。 - bvdb

22

如果`body`标签不做任何事情,HTML和CSS就可以正常工作,你也可以写得很好。

<body scroll="no" style="overflow: hidden">
在这种情况下,应该覆盖body标签,这样更容易控制,但有时会带来麻烦。

41
这不是有效的HTML5。 - mbomb007
1
@mbomb007,您能否请评论一下与HTML5相关的错误? - Ethan
19
@Ethan,“scroll”属性在“<body>”标签上无效。根据我所查找到的任何规范,它都不被列为有效属性。 w3schools; MDN; Quackit - mbomb007

18

这篇文章非常有用,但是我想分享一种可能会帮助其他人的略微不同的方法:

与其使用 height,使用 max-height 也可以达到同样的效果。在我的情况下,我基于类切换来禁用滚动条。当容器的高度小于视口的高度时,设置 .someContainer {height: 100%; overflow: hidden;} 会拉伸容器,这不是你想要的结果。设置 max-height 可以解决这个问题,但如果内容变化时容器的高度大于视口的高度,仍然会禁用滚动。


这个解决方案适用于桌面浏览器,而且没有不必要的滚动条顶部副作用,真是救了我的一天。但在移动浏览器(iPhone5s 和 Android)上无效。 - bob

11
  • 使用React >= 17.8?
  • 想要有条件地执行此操作?

useEffect 来拯救!

function useImperativeDisableScroll({ element, disabled }) {
    useEffect(() => {
        if (!element) {
            return
        }

        element.style.overflowY = disabled ? 'hidden' : 'scroll'

        return () => {
            element.style.overflowY = 'scroll'
        }
    }, [disabled])
}

您可以将其与例如以下内容一起使用:

useImperativeDisableScroll({ element: document.body, disabled: true })

根据您的使用情况,也许会有更好的运气。
useImperativeDisableScroll({
    element: document.scrollingElement,
    disabled: true
})

但请注意,目前(写作时)可能需要使用polyfill来实现document.scrollingElement

有用的链接:


9

当你需要为你的Web应用程序创建弹出式组件时,还有一种方便的方法可以禁用滚动而无需动态更改body元素。 首先,添加此样式:

body:has(.requires-no-scroll) {
  overflow: hidden;
}

接下来,当你创建/打开任何弹出窗口时,只需向其添加此类,并且它的存在将自动阻止滚动(在删除弹出窗口时解除阻止):

<div class="popup requires-no-scroll">
  ...
</div>

当您基于一些反应性布尔变量显示弹出窗口时,这对于反应式应用程序非常有用:滚动本身被阻止,您不需要做任何其他事情。


我喜欢这个优雅的解决方案(忽略可能昂贵的选择器)。当我尝试使用 overscroll-behavior 解决方案失败时,它起作用了。:has 在 Firefox 中仍然无法工作,但没关系。 - dakab

4
这将防止页面滚动:
body, html {
  overflow: hidden
}

4

为什么不试试这个:

<style type="text/css">
html, body {
  overflow: hidden;
}
</style>

2

如果您可以接受页面滚动到顶部,可以这样做:

position: fixed;

在你不想滚动的元素上添加CSS属性。我知道这不是你想要的答案,但我直接回答了标题,以方便那些通过Google搜索此问题的人。

1

HTML

<body id="appBody">
....
</body>

JS

function disableBodyScroll(){
 const element = document.querySelector("#appBody");
 element.classList.add("stop-scroll");
}

function enableBodyScroll(){
 const element = document.querySelector("#appBody");
 element.classList.remove("stop-scroll");
}

CSS

 .stop-scroll {
      margin: 0;
      height: 100%;
      overflow: hidden;
    }

BBC似乎使用了一些组合,可以通过设置类似以下内容使其可见: height: 200vh; max-height: 200vh; overflow: auto; 在主元素上。他们如何实际防止滚动并不明显。例如:https://www.bbc.co.uk/news/uk-england-tyne-58925807 - Daniel
也可以通过禁用 JavaScript 来规避此问题。 - Daniel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接