[css] overscroll-behavior 你就用吧,一用一个不吱声

2026-04-13 12:591阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐
问题描述:

经常写移动端WEB的都知道,浏览器会在列表滚动完毕后加一个回弹效果:



那么如何去掉呢?我们随便搜索一篇靠前的回答,你可能会搜索到这个:
sb CSDN1376×602 90.6 KB


一看,唉,一行代码就能解决 ?!强强!?
马上Ctrl c + Ctrl v

加完发现:唉,怎么没用?
这时候可能有小朋友会说:body没用那是不是应该加到滚动元素上呢?
那么新的问题又来了:唉,那你怎么知道哪个是滚动元素呢?

于是,聪明的你可能会写出以下代码:

* { overscroll-behavior: none; }
然后你用手机测试,会发现问题解决了,回弹没有了,然后信心满满得提交了代码

第二天:
测试:唉,怎么有部分页面的列表滚不动?
你 :你用的什么浏览器?我这里没问题啊?
测试:电脑上浏览器的开发者工具模拟的,没用真机
你 :那你用手机试试
测试:手机可以唉
你 :那应该是浏览器开发者工具的bug,不管吧

直到某一天,领导提了bug过来:你们这写的是什么代码啊?为什么我手机上有部分页面的列表滚不动呢?
你:啊?

那恭喜你发现了这个样式最大的坑点:当滚动列表是祖先元素,并且子元素恰好有overflow: auto/hidden和overscroll-behavior: contain/none时,会出现页面无法滚动,只能手动拖动滚动条的情况

我们来看下面这个栗子(有条件的童鞋可以前往codesandbox查看和调试):

HTML代码

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Scroll Bug Test</title> <style> body { height: 600px; overflow-y: auto; } .container { font-size: 16px; overflow: hidden; overscroll-behavior: contain; } </style> </head> <body> <div class="container"></div> <script> const container = document.querySelector(".container"); for (let i = 0; i < 255; i++) { const p = document.createElement("p"); p.innerText = i; container.appendChild(p); } </script> </body> </html>

这个网页只有一个滚动列表(body)、一个文本盒子(.container)和一堆js生成的p标签(用来撑开盒子)
由于滚轮/触摸手势是从 .container 上开始的
浏览器会先尝试让 .container 处理这次滚动。此时:

  1. .containeroverflow: hidden。而MDN 对 overflow: hidden 的说明是:

    Overflow content is clipped at the element’s padding box. There are no scroll bars, and the clipped content is not visible (i.e., clipped content is hidden), but the content still exists. User agents do not add scroll bars and also do not allow users to view the content outside the clipped region by actions such as dragging on a touch screen or using the scroll wheel on a mouse. The content can be scrolled programmatically (for example, by linking to anchor text, by tabbing to a hidden yet focusable element, or by setting the value of the scrollLeft property or the scrollTo() method), in which case the element box is a scroll container.

    翻译过来意思就是:

    如果需要,内容将被裁减以适应边距(padding)盒。不提供滚动条,也不支持允许用户滚动(例如通过拖拽或者使用滚轮)。内容可以编程的方式滚动(例如,通过设置 scrollLeft 等属性的值或 scrollTo() 方法), 因此该元素仍然是一个滚动的容器

  2. overscroll 规范里又说:

    Scroll boundary refers to when the scroll position of a scroll container reaches the edge of the scrollport. If a scroll container has no potential to scroll, because it does not overflow in the direction of the scroll, the element is always considered to be at the scroll boundary.

    翻译过来意思就是:

    滚动边界​指的是当滚动容器的滚动位置到达滚动视口边缘时的状态。如果一个滚动容器在滚动方向上没有溢出的可能性(即无可滚动内容),则该元素始终被视为处于滚动边界

  3. overscroll-behavior: contain 的语义正是:到达边界后,不允许把滚动链继续传给祖先

于是结果就是:

  • 鼠标滚轮 / 触摸滑动落在 .container
  • .container 自己又不能用户滚动
  • 它还被视为一开始就在边界
  • contain 阻止把这次滚动继续链到 body
  • 所以你看到的是:页面无法滚动,只能手动拖动滚动条

那么到底要如何解决开头提到的回弹效果呢?

答案是加在html身上即可

html { overscroll-behavior: none; }

你猜对了吗

以上内容均为真实经历,这个问题真的卡了我好几天555



参考:

  1. Y-axis scroll blocked in Chrome when consecutive containers have overflow-y and overscroll-behavior - chromium issues
  2. CSS Overscroll Behavior Module Level 1 - W3C
  3. overflow - CSS - MDN
网友解答:
--【壹】--:

经常写移动端WEB的都知道,浏览器会在列表滚动完毕后加一个回弹效果:



那么如何去掉呢?我们随便搜索一篇靠前的回答,你可能会搜索到这个:
sb CSDN1376×602 90.6 KB


一看,唉,一行代码就能解决 ?!强强!?
马上Ctrl c + Ctrl v

加完发现:唉,怎么没用?
这时候可能有小朋友会说:body没用那是不是应该加到滚动元素上呢?
那么新的问题又来了:唉,那你怎么知道哪个是滚动元素呢?

于是,聪明的你可能会写出以下代码:

* { overscroll-behavior: none; }
然后你用手机测试,会发现问题解决了,回弹没有了,然后信心满满得提交了代码

第二天:
测试:唉,怎么有部分页面的列表滚不动?
你 :你用的什么浏览器?我这里没问题啊?
测试:电脑上浏览器的开发者工具模拟的,没用真机
你 :那你用手机试试
测试:手机可以唉
你 :那应该是浏览器开发者工具的bug,不管吧

直到某一天,领导提了bug过来:你们这写的是什么代码啊?为什么我手机上有部分页面的列表滚不动呢?
你:啊?

那恭喜你发现了这个样式最大的坑点:当滚动列表是祖先元素,并且子元素恰好有overflow: auto/hidden和overscroll-behavior: contain/none时,会出现页面无法滚动,只能手动拖动滚动条的情况

我们来看下面这个栗子(有条件的童鞋可以前往codesandbox查看和调试):

HTML代码

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Scroll Bug Test</title> <style> body { height: 600px; overflow-y: auto; } .container { font-size: 16px; overflow: hidden; overscroll-behavior: contain; } </style> </head> <body> <div class="container"></div> <script> const container = document.querySelector(".container"); for (let i = 0; i < 255; i++) { const p = document.createElement("p"); p.innerText = i; container.appendChild(p); } </script> </body> </html>

这个网页只有一个滚动列表(body)、一个文本盒子(.container)和一堆js生成的p标签(用来撑开盒子)
由于滚轮/触摸手势是从 .container 上开始的
浏览器会先尝试让 .container 处理这次滚动。此时:

  1. .containeroverflow: hidden。而MDN 对 overflow: hidden 的说明是:

    Overflow content is clipped at the element’s padding box. There are no scroll bars, and the clipped content is not visible (i.e., clipped content is hidden), but the content still exists. User agents do not add scroll bars and also do not allow users to view the content outside the clipped region by actions such as dragging on a touch screen or using the scroll wheel on a mouse. The content can be scrolled programmatically (for example, by linking to anchor text, by tabbing to a hidden yet focusable element, or by setting the value of the scrollLeft property or the scrollTo() method), in which case the element box is a scroll container.

    翻译过来意思就是:

    如果需要,内容将被裁减以适应边距(padding)盒。不提供滚动条,也不支持允许用户滚动(例如通过拖拽或者使用滚轮)。内容可以编程的方式滚动(例如,通过设置 scrollLeft 等属性的值或 scrollTo() 方法), 因此该元素仍然是一个滚动的容器

  2. overscroll 规范里又说:

    Scroll boundary refers to when the scroll position of a scroll container reaches the edge of the scrollport. If a scroll container has no potential to scroll, because it does not overflow in the direction of the scroll, the element is always considered to be at the scroll boundary.

    翻译过来意思就是:

    滚动边界​指的是当滚动容器的滚动位置到达滚动视口边缘时的状态。如果一个滚动容器在滚动方向上没有溢出的可能性(即无可滚动内容),则该元素始终被视为处于滚动边界

  3. overscroll-behavior: contain 的语义正是:到达边界后,不允许把滚动链继续传给祖先

于是结果就是:

  • 鼠标滚轮 / 触摸滑动落在 .container
  • .container 自己又不能用户滚动
  • 它还被视为一开始就在边界
  • contain 阻止把这次滚动继续链到 body
  • 所以你看到的是:页面无法滚动,只能手动拖动滚动条

那么到底要如何解决开头提到的回弹效果呢?

答案是加在html身上即可

html { overscroll-behavior: none; }

你猜对了吗

以上内容均为真实经历,这个问题真的卡了我好几天555



参考:

  1. Y-axis scroll blocked in Chrome when consecutive containers have overflow-y and overscroll-behavior - chromium issues
  2. CSS Overscroll Behavior Module Level 1 - W3C
  3. overflow - CSS - MDN
标签:软件开发
问题描述:

经常写移动端WEB的都知道,浏览器会在列表滚动完毕后加一个回弹效果:



那么如何去掉呢?我们随便搜索一篇靠前的回答,你可能会搜索到这个:
sb CSDN1376×602 90.6 KB


一看,唉,一行代码就能解决 ?!强强!?
马上Ctrl c + Ctrl v

加完发现:唉,怎么没用?
这时候可能有小朋友会说:body没用那是不是应该加到滚动元素上呢?
那么新的问题又来了:唉,那你怎么知道哪个是滚动元素呢?

于是,聪明的你可能会写出以下代码:

* { overscroll-behavior: none; }
然后你用手机测试,会发现问题解决了,回弹没有了,然后信心满满得提交了代码

第二天:
测试:唉,怎么有部分页面的列表滚不动?
你 :你用的什么浏览器?我这里没问题啊?
测试:电脑上浏览器的开发者工具模拟的,没用真机
你 :那你用手机试试
测试:手机可以唉
你 :那应该是浏览器开发者工具的bug,不管吧

直到某一天,领导提了bug过来:你们这写的是什么代码啊?为什么我手机上有部分页面的列表滚不动呢?
你:啊?

那恭喜你发现了这个样式最大的坑点:当滚动列表是祖先元素,并且子元素恰好有overflow: auto/hidden和overscroll-behavior: contain/none时,会出现页面无法滚动,只能手动拖动滚动条的情况

我们来看下面这个栗子(有条件的童鞋可以前往codesandbox查看和调试):

HTML代码

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Scroll Bug Test</title> <style> body { height: 600px; overflow-y: auto; } .container { font-size: 16px; overflow: hidden; overscroll-behavior: contain; } </style> </head> <body> <div class="container"></div> <script> const container = document.querySelector(".container"); for (let i = 0; i < 255; i++) { const p = document.createElement("p"); p.innerText = i; container.appendChild(p); } </script> </body> </html>

这个网页只有一个滚动列表(body)、一个文本盒子(.container)和一堆js生成的p标签(用来撑开盒子)
由于滚轮/触摸手势是从 .container 上开始的
浏览器会先尝试让 .container 处理这次滚动。此时:

  1. .containeroverflow: hidden。而MDN 对 overflow: hidden 的说明是:

    Overflow content is clipped at the element’s padding box. There are no scroll bars, and the clipped content is not visible (i.e., clipped content is hidden), but the content still exists. User agents do not add scroll bars and also do not allow users to view the content outside the clipped region by actions such as dragging on a touch screen or using the scroll wheel on a mouse. The content can be scrolled programmatically (for example, by linking to anchor text, by tabbing to a hidden yet focusable element, or by setting the value of the scrollLeft property or the scrollTo() method), in which case the element box is a scroll container.

    翻译过来意思就是:

    如果需要,内容将被裁减以适应边距(padding)盒。不提供滚动条,也不支持允许用户滚动(例如通过拖拽或者使用滚轮)。内容可以编程的方式滚动(例如,通过设置 scrollLeft 等属性的值或 scrollTo() 方法), 因此该元素仍然是一个滚动的容器

  2. overscroll 规范里又说:

    Scroll boundary refers to when the scroll position of a scroll container reaches the edge of the scrollport. If a scroll container has no potential to scroll, because it does not overflow in the direction of the scroll, the element is always considered to be at the scroll boundary.

    翻译过来意思就是:

    滚动边界​指的是当滚动容器的滚动位置到达滚动视口边缘时的状态。如果一个滚动容器在滚动方向上没有溢出的可能性(即无可滚动内容),则该元素始终被视为处于滚动边界

  3. overscroll-behavior: contain 的语义正是:到达边界后,不允许把滚动链继续传给祖先

于是结果就是:

  • 鼠标滚轮 / 触摸滑动落在 .container
  • .container 自己又不能用户滚动
  • 它还被视为一开始就在边界
  • contain 阻止把这次滚动继续链到 body
  • 所以你看到的是:页面无法滚动,只能手动拖动滚动条

那么到底要如何解决开头提到的回弹效果呢?

答案是加在html身上即可

html { overscroll-behavior: none; }

你猜对了吗

以上内容均为真实经历,这个问题真的卡了我好几天555



参考:

  1. Y-axis scroll blocked in Chrome when consecutive containers have overflow-y and overscroll-behavior - chromium issues
  2. CSS Overscroll Behavior Module Level 1 - W3C
  3. overflow - CSS - MDN
网友解答:
--【壹】--:

经常写移动端WEB的都知道,浏览器会在列表滚动完毕后加一个回弹效果:



那么如何去掉呢?我们随便搜索一篇靠前的回答,你可能会搜索到这个:
sb CSDN1376×602 90.6 KB


一看,唉,一行代码就能解决 ?!强强!?
马上Ctrl c + Ctrl v

加完发现:唉,怎么没用?
这时候可能有小朋友会说:body没用那是不是应该加到滚动元素上呢?
那么新的问题又来了:唉,那你怎么知道哪个是滚动元素呢?

于是,聪明的你可能会写出以下代码:

* { overscroll-behavior: none; }
然后你用手机测试,会发现问题解决了,回弹没有了,然后信心满满得提交了代码

第二天:
测试:唉,怎么有部分页面的列表滚不动?
你 :你用的什么浏览器?我这里没问题啊?
测试:电脑上浏览器的开发者工具模拟的,没用真机
你 :那你用手机试试
测试:手机可以唉
你 :那应该是浏览器开发者工具的bug,不管吧

直到某一天,领导提了bug过来:你们这写的是什么代码啊?为什么我手机上有部分页面的列表滚不动呢?
你:啊?

那恭喜你发现了这个样式最大的坑点:当滚动列表是祖先元素,并且子元素恰好有overflow: auto/hidden和overscroll-behavior: contain/none时,会出现页面无法滚动,只能手动拖动滚动条的情况

我们来看下面这个栗子(有条件的童鞋可以前往codesandbox查看和调试):

HTML代码

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Scroll Bug Test</title> <style> body { height: 600px; overflow-y: auto; } .container { font-size: 16px; overflow: hidden; overscroll-behavior: contain; } </style> </head> <body> <div class="container"></div> <script> const container = document.querySelector(".container"); for (let i = 0; i < 255; i++) { const p = document.createElement("p"); p.innerText = i; container.appendChild(p); } </script> </body> </html>

这个网页只有一个滚动列表(body)、一个文本盒子(.container)和一堆js生成的p标签(用来撑开盒子)
由于滚轮/触摸手势是从 .container 上开始的
浏览器会先尝试让 .container 处理这次滚动。此时:

  1. .containeroverflow: hidden。而MDN 对 overflow: hidden 的说明是:

    Overflow content is clipped at the element’s padding box. There are no scroll bars, and the clipped content is not visible (i.e., clipped content is hidden), but the content still exists. User agents do not add scroll bars and also do not allow users to view the content outside the clipped region by actions such as dragging on a touch screen or using the scroll wheel on a mouse. The content can be scrolled programmatically (for example, by linking to anchor text, by tabbing to a hidden yet focusable element, or by setting the value of the scrollLeft property or the scrollTo() method), in which case the element box is a scroll container.

    翻译过来意思就是:

    如果需要,内容将被裁减以适应边距(padding)盒。不提供滚动条,也不支持允许用户滚动(例如通过拖拽或者使用滚轮)。内容可以编程的方式滚动(例如,通过设置 scrollLeft 等属性的值或 scrollTo() 方法), 因此该元素仍然是一个滚动的容器

  2. overscroll 规范里又说:

    Scroll boundary refers to when the scroll position of a scroll container reaches the edge of the scrollport. If a scroll container has no potential to scroll, because it does not overflow in the direction of the scroll, the element is always considered to be at the scroll boundary.

    翻译过来意思就是:

    滚动边界​指的是当滚动容器的滚动位置到达滚动视口边缘时的状态。如果一个滚动容器在滚动方向上没有溢出的可能性(即无可滚动内容),则该元素始终被视为处于滚动边界

  3. overscroll-behavior: contain 的语义正是:到达边界后,不允许把滚动链继续传给祖先

于是结果就是:

  • 鼠标滚轮 / 触摸滑动落在 .container
  • .container 自己又不能用户滚动
  • 它还被视为一开始就在边界
  • contain 阻止把这次滚动继续链到 body
  • 所以你看到的是:页面无法滚动,只能手动拖动滚动条

那么到底要如何解决开头提到的回弹效果呢?

答案是加在html身上即可

html { overscroll-behavior: none; }

你猜对了吗

以上内容均为真实经历,这个问题真的卡了我好几天555



参考:

  1. Y-axis scroll blocked in Chrome when consecutive containers have overflow-y and overscroll-behavior - chromium issues
  2. CSS Overscroll Behavior Module Level 1 - W3C
  3. overflow - CSS - MDN
标签:软件开发