53

In the example below, I would like to reduce the scroll speed of the div's content, especially when using the mouse wheel, as one wheel tick scrolls approximately the div's height.

Is it possible to control that with CSS, and if not, javascript (perhaps using jQuery) ?

.scrollable {
    width: 500px;
    height: 70px;
    overflow: auto; 
}
<div class="scrollable">
    Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?
</div>

Note: I realize that the scroll speed might differ between os/browers and browser settings. But I think that in the majority of the cases, the scroll speed (when using the mouse wheel) is too fast, so I would like to slow it down.

Benjamin Crouzier
  • 40,265
  • 44
  • 171
  • 236

5 Answers5

92

The scroll speed CAN be changed, adjusted, reversed, all of the above - via javascript (or a js library such as jQuery).

WHY would you want to do this? Parallax is just one of the reasons. I have no idea why anyone would argue against doing so -- the same negative arguments can be made against hiding DIVs, sliding elements up/down, etc. Websites are always a combination of technical functionality and UX design -- a good designer can use almost any technical capability to improve UX. That is what makes him/her good.

Toni Almeida of Portugal created a brilliant demo, reproduced below:

jsFiddle Demo

HTML:

<div id="myDiv">
    Use the mouse wheel (not the scroll bar) to scroll this DIV. You will see that the scroll eventually slows down, and then stops. <span class="boldit">Use the mouse wheel (not the scroll bar) to scroll this DIV. You will see that the scroll eventually slows down, and then stops. </span>
</div>

javascript/jQuery:

  function wheel(event) {
      var delta = 0;
      if (event.wheelDelta) {(delta = event.wheelDelta / 120);}
      else if (event.detail) {(delta = -event.detail / 3);}

      handle(delta);
      if (event.preventDefault) {(event.preventDefault());}
      event.returnValue = false;
  }

  function handle(delta) {
      var time = 1000;
      var distance = 300;

      $('html, body').stop().animate({
          scrollTop: $(window).scrollTop() - (distance * delta)
      }, time );
  }

  if (window.addEventListener) {window.addEventListener('DOMMouseScroll', wheel, false);}
    window.onmousewheel = document.onmousewheel = wheel;

Source:

How to change default scrollspeed,scrollamount,scrollinertia of a webpage

Community
  • 1
  • 1
cssyphus
  • 37,875
  • 18
  • 96
  • 111
16

The mouse scroll even can be overwritten using JS within the browser using an event listener. It is possible to prevent default scrolling behavior this way, and implement your own behavior (see cssyphus's answer).

However, I think doing so is a HORRIBLE idea in terms of usability, accessibility, and respect for your users.

ICW
  • 4,875
  • 5
  • 27
  • 33
cdeszaq
  • 30,869
  • 25
  • 117
  • 173
  • 7
    *Once you can capture the scroll event (assuming you can)* - **$(window).scroll()** See my answer for more. – cssyphus Oct 15 '14 at 15:27
  • 17
    As per other answers on this page, this answer is incorrect and, in its current state is misleading to viewers. Please consider updating your answer. – U007D May 02 '17 at 14:07
  • 1
    It may be a horrible idea, but not changing the speed is sometimes even more HORRIBLE. Fo example, I've got a table with 300 rows and when I try really hard, I can scroll by 3 rows at once. That's unusable. – maaartinus Feb 07 '19 at 03:49
  • Ultimately, the scroll is an animation, rather than a jump. I'm guessing you consider control over any elements' animations in pages you develop a legitimate right. And it should be your responsibility, as a frontend developer. Right? Why would you think differently when we're talking about an almost inevitable animation on the root element? – tao Mar 21 '20 at 16:51
3

I just made a pure Javascript function based on that code. Javascript only version demo: http://jsbin.com/copidifiji

That is the independent code from jQuery

if (window.addEventListener) {window.addEventListener('DOMMouseScroll', wheel, false); 
window.onmousewheel = document.onmousewheel = wheel;}

function wheel(event) {
    var delta = 0;
    if (event.wheelDelta) delta = (event.wheelDelta)/120 ;
    else if (event.detail) delta = -(event.detail)/3;

    handle(delta);
    if (event.preventDefault) event.preventDefault();
    event.returnValue = false;
}

function handle(sentido) {
    var inicial = document.body.scrollTop;
    var time = 1000;
    var distance = 200;
  animate({
    delay: 0,
    duration: time,
    delta: function(p) {return p;},
    step: function(delta) {
window.scrollTo(0, inicial-distance*delta*sentido);   
    }});}

function animate(opts) {
  var start = new Date();
  var id = setInterval(function() {
    var timePassed = new Date() - start;
    var progress = (timePassed / opts.duration);
    if (progress > 1) {progress = 1;}
    var delta = opts.delta(progress);
    opts.step(delta);
    if (progress == 1) {clearInterval(id);}}, opts.delay || 10);
}
user3768564
  • 274
  • 3
  • 9
0

A short and straightforward vanilla js solution to increase/decrease scrolling speed/step(deltaY):

    let custom_scroll = document.getElementById('custom-scroll');
    let scroll_timeout = undefined;
    let ratio = 0.25;//change this to increase/descrease scroll speed/step
    custom_scroll.addEventListener("wheel", (event) => {
        event.preventDefault();

        clearTimeout(scroll_timeout);//if the previous scroll didn't finish, need to stop it to prevent infinite scroll.

        let target = custom_scroll.scrollTop + event.deltaY * ratio;
        let step = target > custom_scroll.scrollTop ? 1 : -1;

        let frame = () => {
            custom_scroll.scrollTop += step;
            if((target < custom_scroll.scrollTop && step < 0) || (target > custom_scroll.scrollTop && step > 0)) {
              scroll_timeout = setTimeout(frame, 5);
            }
        }
        frame();
    });

//or even shorter version:
let custom_scroll_short = document.getElementById('custom-scroll-short');
custom_scroll_short.addEventListener("wheel", (event) => {
      event.preventDefault();

      let target = custom_scroll_short.scrollTop + event.deltaY * ratio;

      custom_scroll_short.scrollTo({
        top: target,
        behavior: "smooth"
      })
});
#custom-scroll, #custom-scroll-short {
      width: 200px;
      height: 100px;
      background-color: gray;
      overflow-y: scroll;
      margin: 50px;
    }
<div id="custom-scroll">
        <p>Item</p>
        <p>Item</p>
        <p>Item</p>
        <p>Item</p>
        <p>Item</p>
        <p>Item</p>
        <p>Item</p>
        <p>Item</p>
        <p>Item</p>
        <p>Item</p>
    </div>

    <div id="custom-scroll-short">
        <p>Item</p>
        <p>Item</p>
        <p>Item</p>
        <p>Item</p>
        <p>Item</p>
        <p>Item</p>
        <p>Item</p>
        <p>Item</p>
        <p>Item</p>
        <p>Item</p>
    </div>
someone
  • 46
  • 3
0

In addition to previous answers it's also important to reply this part of the original question:

"Is it possible ... with CSS?

The (auto) scroll behavior can be set to 'smooth' but speed is set by the browser.

html { scroll-behavior: smooth; }

In this case, saldy the answer is no: the smooth scrolling speed cannot be set or changed using CSS. This property is handled by the browser.

In Firefox for example you can play with general.smoothScroll options and values in the about:config browser tab, but be sure not to tamper other important settings that can be changed there.

Sanxofon
  • 759
  • 9
  • 20