141

In Chrome for Mac, one can "overscroll" a page (for lack of a better word), as shown in the screenshot below, to see "what's behind", similar to the iPad or iPhone.

I've noticed that some pages have it disabled, like gmail and the "new tab" page.

How can I disable "overscrolling"? Are there other ways in which I can control "overscrolling"?

enter image description here

sjagr
  • 15,983
  • 5
  • 40
  • 67
Randomblue
  • 112,777
  • 145
  • 353
  • 547
  • 2
    I'm actually trying to *enable* it on the newtab page, for example. Trying to understand the issues involved here. – Randomblue Aug 20 '12 at 22:58
  • I don't think there is a way to do that. It's a simple matter of having the page be long enough to allow the scroller to start. Also, consider changing the title of your post to what you would like to achieve instead of the opposite. – Jon Egeland Aug 20 '12 at 23:00

8 Answers8

189

The accepted solution was not working for me. The only way I got it working while still being able to scroll is:

html {
    overflow: hidden;
    height: 100%;
}

body {
    height: 100%;
    overflow: auto;
}
Florian Feldhaus
  • 5,567
  • 2
  • 38
  • 46
  • 2
    This solution is problematic for both devices that don't respect the `html` styling hack and for mobile web browsers which look at the full overflow of `body` disregarding the height to which `html` was set. – runspired Jul 07 '15 at 19:46
  • 6
    This solution doesn't work as of Chrome 46 for Mac. It prevents over-scrolling but none of the child elements are scrollable. – Daniel Bonnell Oct 31 '15 at 17:01
  • 1
    Then, how can you get the scrollTop value that you'd usually get with `$(window).scrollTop` ? – Guig Apr 20 '16 at 19:37
  • 2
    Neither solution works for me on Chrome 49 for mac or Firefox 44 for mac. `window.scrollY` is always `0`. – momo Apr 22 '16 at 21:40
  • 4
    Works for Chrome, but not Safari. – Bretton Wade Aug 03 '16 at 21:47
  • If I had to be pedantic I kinda prefer `height: 100vh. It's well supported with the exception of IE8 http://caniuse.com/#feat=viewport-units – Ryan Taylor Dec 01 '16 at 14:47
  • This solution works for me in Chrome but breaks my jQuery smooth scrolling event handler. Anyone have a solution? My jQuery smooth scroll: `$('a[href*=\\#]').on('click', function(event){ event.preventDefault(); $('html,body').animate({scrollTop:$(this.hash).offset().top}, 500); });` – Kyle Vassella Dec 20 '16 at 21:43
  • Using this in Chrome still gives me a small bounce of a couple of pixels at the bottom of the page – Joris Mans Nov 16 '17 at 15:35
  • Chrome and most browsers other than Safari now support overscroll behavior in css: https://caniuse.com/#feat=css-overscroll-behavior – Dtipson Feb 05 '19 at 16:25
  • `css-overflow` is not supported in mobile browsers that it's kind of the whole point of using it. – ggwzrd Apr 17 '19 at 15:44
  • this solution breaks scrolling event... `window.addEventListener('scroll', () => something` – Vladyslav Tereshyn Jul 30 '19 at 13:05
  • It won't scroll on y direction if your body height is greater than 100%. – Wayne Wei Sep 16 '19 at 05:37
  • This can cause some unexpected results, especially if you use parallax effects etc. Consider @Koslun's answer instead. – Adrian Mar 18 '20 at 22:21
  • Using `overflow: hidden` on top level elements like `body` and `html` will make it impossible to use any sticky positioning. Individual elements that have overflow should be corrected or have wrappers with `overflow: hidden`. – Brett Jackson Dec 29 '20 at 22:18
124

In Chrome 63+, Firefox 59+ and Opera 50+ you can do this in CSS:

body {
  overscroll-behavior-y: none;
}

This disables the rubberbanding effect on iOS shown in the screenshot of the question. It however also disables pull-to-refresh, glow effects and scroll chaining.

You can however elect to implement your own effect or functionality upon over-scrolling. If you for instance want to blur the page and add a neat animation:

<style>
  body.refreshing #inbox {
    filter: blur(1px);
    touch-action: none; /* prevent scrolling */
  }
  body.refreshing .refresher {
    transform: translate3d(0,150%,0) scale(1);
    z-index: 1;
  }
  .refresher {
    --refresh-width: 55px;
    pointer-events: none;
    width: var(--refresh-width);
    height: var(--refresh-width);
    border-radius: 50%; 
    position: absolute;
    transition: all 300ms cubic-bezier(0,0,0.2,1);
    will-change: transform, opacity;
    ...
  }
</style>

<div class="refresher">
  <div class="loading-bar"></div>
  <div class="loading-bar"></div>
  <div class="loading-bar"></div>
  <div class="loading-bar"></div>
</div>

<section id="inbox"><!-- msgs --></section>

<script>
  let _startY;
  const inbox = document.querySelector('#inbox');

  inbox.addEventListener('touchstart', e => {
    _startY = e.touches[0].pageY;
  }, {passive: true});

  inbox.addEventListener('touchmove', e => {
    const y = e.touches[0].pageY;
    // Activate custom pull-to-refresh effects when at the top of the container
    // and user is scrolling up.
    if (document.scrollingElement.scrollTop === 0 && y > _startY &&
        !document.body.classList.contains('refreshing')) {
      // refresh inbox.
    }
  }, {passive: true});
</script>

Browser Support

As of this writing Chrome 63+, Firefox 59+ and Opera 50+ support it. Edge publically supported it while Safari is an unknown. Track progress here and current browser compatibility at MDN documentation

More information

Koslun
  • 2,164
  • 1
  • 23
  • 17
  • 6
    This is the best solution, in my opinion. And simple. The one with all the upvotes can be problematic. – TheTC Nov 21 '19 at 18:51
  • 1
    any other solution for edge browser users? – YTG Sep 22 '20 at 19:04
  • 1
    @YTG This property has worked bug-free in Edge as well since version 79 when it got converted to use Chromium under-the-hood. The property also somewhat worked in the prior version, 18 but through a bug. Alternatively the other solution not using overscroll-behaviour-y property should work in earlier versions of Edge than those. 18 and in particular 79+ do however seem to cover most Edge users. See more about browser support here: https://caniuse.com/css-overscroll-behavior. The MDN link appears to currently be slightly out-of-date in regards to Edge support. – Koslun Sep 23 '20 at 16:12
  • 1
    wow superhero solution here!! This fixes a scroll-padding issue on microsoft edge where page doesn't return to top-0 on overscrolling.. – piouson Oct 19 '22 at 07:26
  • 3
    This worked for me by adding overscroll-behavior-y property in both html AND body. – db306 Nov 28 '22 at 15:33
42

One way you can prevent this, is using the following CSS:

html, body {
    width: 100%;
    height: 100%;
    overflow: hidden;
}

body > div {
    height: 100%;
    overflow: scroll;
    -webkit-overflow-scrolling: touch;
}

This way the body has never any overflow and won't "bounce" when scrolling at the top and bottom of the page. The container will perfectly scroll its content within. This works in Safari and in Chrome.

Edit

Why the extra <div>-element as a wrapper could be useful:
Florian Feldhaus' solution uses slightly less code and works fine too. However, it can have a little quirk, when it comes to content that exceeds the viewport width. In this case the scrollbar at the bottom of the window is moved out of the viewport half way and is hard to recognize/reach. This can be avoided using body { margin: 0; } if suitable. In situation where you can't add this CSS the wrapper element is useful as the scrollbar is always fully visible.

Find a screenshot below: enter image description here

Community
  • 1
  • 1
insertusernamehere
  • 23,204
  • 9
  • 87
  • 126
  • 3
    If this worked once, it no longer works. In my Chrome v37, the overscoll behaviour will happen wherever an element scrolls. – bbsimonbb Oct 31 '14 at 08:30
  • @user1585345 I've tested this right now in Chrome 38 again on OS X and it still works (also in Safari). Here's the file I'm using. Can you test it with this file? [Direct link to the file on sendspace.com](https://fs12n5.sendspace.com/dl/37b0fc1e44b648deed4182980d270e20/54536f00308e7e05/qfffk1/test.html). – insertusernamehere Oct 31 '14 at 11:16
  • 1
    I've tested with the above file, and I still have the bounce. I suspect we will not get to the bottom of this mystery. Chrome 37 – bbsimonbb Nov 03 '14 at 11:01
  • You shouldn't need the extra wrapper div. Check the below answer for a better solution. – JayD3e Mar 24 '15 at 14:12
  • @JayD3e Thanks for your feedback. Please see my updated answer with an explanation on why the extra wrapper is useful. – insertusernamehere Mar 25 '15 at 10:36
  • 1
    This solution doesn't work as of Chrome 46 for Mac. It prevents over-scrolling but none of the child elements are scrollable. – Daniel Bonnell Oct 31 '15 at 17:02
  • This is bad in mobile safari because it will prevent the navigation bar from tucking away when you scroll. – Jason Axelson Sep 19 '16 at 23:53
3

You can use this code to remove touchmove predefined action:

document.body.addEventListener('touchmove', function(event) {
  console.log(event.source);
  //if (event.source == document.body)
    event.preventDefault();
}, false);
Daniel Prol
  • 94
  • 1
  • 10
2

Try this way

body {
    height: 100vh;
    background-size: cover;
    overflow: hidden;
}
  • This prevents possible scrolling behavior as well, so not a good idea if you still want to be able to scroll normally. – Yong May 26 '23 at 07:41
1
html,body {
    width: 100%;
    height: 100%;
}
body {
    position: fixed;
    overflow: hidden;
}
0

position: absolute works for me. I've tested on Chrome 50.0.2661.75 (64-bit) and OSX.

body {
  overflow: hidden;
}

// position is important
#element {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  overflow: auto;
}
Raibaz
  • 9,280
  • 10
  • 44
  • 65
Tony Jin
  • 59
  • 3
0

Bounce effect cannot be disabled except the height of webpage equals to window.innerHeight, you can let your sub-elements scroll.

html {
    overflow: hidden;
}
Yibo
  • 1
  • 1