18

Is there a way to animate scrolling with CSS3?

Something like this?

@-webkit-keyframes scrolltoview
{
    0%   { scrollTop: 0; }
    100% { scrollTop: 30%; }
}

How to put in the css where's the staring point of the animation?

Ross
  • 17,612
  • 7
  • 42
  • 62
Spiff
  • 3,234
  • 4
  • 17
  • 40
  • No because you can't even scroll without animation in css. – noob Apr 21 '12 at 17:19
  • Can you clarify what you mean by "animate scrolling"? Scrolling, while mundane, is a form of animation. How would you animate it further? – Anthony Apr 21 '12 at 17:22
  • @Micha You're right I can't do it even without Animation. – Spiff Apr 21 '12 at 17:26
  • @Anthony Suppose that you are on top of a TextArea and you want to scroll this (in your code)to the bottom, Without animation it will just jump to the bottom. With animation it will be done smoothly. Think of iPhone for example. – Spiff Apr 21 '12 at 17:31

5 Answers5

15

As explained here you can do it using margin-top trick and updating scroll position dynamically. You can check the demo. Code is straight forward:

// Define the variables
var easing, e, pos;
$(function(){
  // Get the click event
  $("#go-top").on("click", function(){
    // Get the scroll pos
    pos= $(window).scrollTop();
    // Set the body top margin
    $("body").css({
      "margin-top": -pos+"px",
      "overflow-y": "scroll", // This property is posed for fix the blink of the window width change 
    });
    // Make the scroll handle on the position 0
    $(window).scrollTop(0);
    // Add the transition property to the body element
    $("body").css("transition", "all 1s ease");
    // Apply the scroll effects
    $("body").css("margin-top", "0");
    // Wait until the transition end
    $("body").on("webkitTransitionEnd transitionend msTransitionEnd oTransitionEnd", function(){
      // Remove the transition property
      $("body").css("transition", "none");
    });
  });
});

@AndrewP provided a nice working example based on this idea

mente
  • 2,476
  • 1
  • 26
  • 31
  • Would there be a nice way to apply the same effect but by using an anchors hash like #home or #services with this code? – Gerben Van Dijk Aug 29 '13 at 11:10
  • 2
    @GerbenVanDijk I’m way late on this one, but I built what I think you asked for (a function to find every link to an anchor on the page and modify their click to scroll via CSS3 + margin-top, tested down to IE 8): http://codepen.io/acusti/pen/bFBDr – Andrew Patton Nov 07 '13 at 17:25
  • @AndrewP unfortunately it doesn't work in Safari 7.0. It scrolls but without animation – mente Nov 08 '13 at 07:47
  • @mente You may have caught it in an awkward broken state when I was modifying or tweaking it. I just checked it again in Safari 7.0 (9537.71) to verify and it animated the scroll quite smoothly. – Andrew Patton Nov 11 '13 at 12:28
  • @mente Astutely observed! Strangely, it was working for me in the edit CodePen view, but on its own, it was broken. I’ve since debugged and fixed (I hope) the problem once and for all. I was trying to use `scrollTop` on the `documentElement`, which failed in Safari, even though it it should be the standards approach. Finally found a solution via http://stackoverflow.com/questions/5371139/window-scrolltop-vs-document-scrolltop#comment20034307_5371386 that works in Safari, Chrome, Firefox, and even IE 8 (http://cdpn.io/bFBDr) – Andrew Patton Nov 13 '13 at 19:15
  • @AndrewP - I am also way late, but thanks. Using it in another project now! – Gerben Van Dijk Nov 23 '13 at 22:49
9

css3 animations work with css properties only. this isn't possible within the confines of css.

David Wick
  • 6,877
  • 2
  • 33
  • 36
4

I discovered a better way to animate scrolling, which is to use JavaScript to translate the document body. The advantages of animating with translate over margin or position is pretty well documented. The bottom line is, when animating elements, the GPU will always do a better job.

Here's an example which calculates the user's current position from the top of the window and then smoothly translate back to the top of the window. Assume that a user click or touch event triggered the backToTop function.

See it in action: https://antibland.github.io/starting_point/

function whichTransitionEvent() {
  var t,
      el          = document.createElement('fakeelement'),
      transitions = {
        'transition':'transitionend',
        'OTransition':'oTransitionEnd',
        'MozTransition':'transitionend',
        'WebkitTransition':'webkitTransitionEnd'
     };

  for (t in transitions){
    if (el.style[t] !== undefined){
      return transitions[t];
    }
  }
}

function backToTop() {
  var pos_from_top  = window.scrollY,
      transitionend = whichTransitionEvent(),
      body          = document.querySelector("body");

  function scrollEndHandler() {
    window.scrollTo(0, 0);
    body.removeAttribute("style");
    body.removeEventListener(transitionend, scrollEndHandler);
  }

  body.style.overflowY = "scroll";
  window.scrollTop = 0;

  body.style.webkitTransition = 'all .5s ease';
  body.style.transition = 'all .5s ease';

  body.style.webkitTransform = "translateY(" + pos_from_top + "px)";
  body.style.transform = "translateY(" + pos_from_top + "px)";

  transitionend && body.addEventListener(transitionend, scrollEndHandler);
}
Andy Hoffman
  • 15,329
  • 3
  • 30
  • 51
  • Don't get confused by the up-votes, there is a dramatic performance improvement using transform over margin-top! – Adi Darachi Dec 30 '18 at 14:12
0

I don't think this is possible with css3, but if I understand your question correctly, it is very easy with jquery.

Check out:

http://demos.flesler.com/jquery/scrollTo/

http://api.jquery.com/scroll/

Connor
  • 1,024
  • 4
  • 15
  • 24
0

This is a very simple .js function i made to animate + scroll a webpage.

var Current_scroll_Y=0;
var Target_scroll_Y=0;
var scroll_Speed = 15;

function animate_Scroll(Y)
{
  Target_scroll_Y = Y;
  screen_Y = Math.floor(window.scrollY);

  //Scroll Down
  if(screen_Y<Y)
  {
    var myWindowScroll = setInterval(function(){ screen_Y = screen_Y+scroll_Speed;  if(screen_Y>=Target_scroll_Y){ clearInterval(myWindowScroll); return;}    window.scrollTo(0, screen_Y); }, 3);   
  }
  //Scroll Up
  if(screen_Y>Y)
  {
    var myWindowScroll = setInterval(function(){ screen_Y = screen_Y-scroll_Speed;  if(screen_Y<=Target_scroll_Y){ clearInterval(myWindowScroll); return;}    window.scrollTo(0, screen_Y); }, 3);  
  } 


}//End animate_Scroll  
Really Nice Code
  • 661
  • 1
  • 8
  • 17