Add animated scroll to top button with CSS and jQuery

In this tutorial, I’ll show you how to add animated back to top button with CSS and jQuery to your website. This light-weight approach will enhance usability with a back to top button whilst making use of hardware-accelerated animation as all animations will be handled by native CSS3 properties.

Add animated scroll to top button with CSS and jQuery

Prerequisites

I am going to assume that you already have hooked jQuery up to your site. The JavaScript should be called below your jQuery script tag to ensure you don’t get an ‘undefined jQuery’ error in your console. I cannot guarantee support for old browsers such as Internet Explorer 10 and below.

 

The approach

The transitions are made by simply adding classes to your body element. The advantage of this approach is that you can completely tailor your animation requirements in the stylesheet without having to change any CSS. Furthermore, there is no need to add a ‘back to top’ anchor to your HTML, this is done by jQuery once the class has been initiated.

Step 1 – Add the JavaScript snippet

Create a new file in your project directory, in this example, I will call it ‘back-to-top,js’. In the file, copy and paste the following snippet in:

/*globals jQuery:false */

(function ($) {
    "use strict";

    var backToTop = function () {

        /** @type {number} */
        this.windowHeight = 0;

        /** @type {number} */
        this.fromTop = 0;

        /** @type {{}} */
        this.body = {};

        /** @type {{}} */
        this.window = {};

        /** @type {{}} */
        this.backToTopCta = {};

        /** @type {{}} */
        this.scrollSelector = {};

        /**
         * Initiates the class.
         *
         * @return {backToTop}
         */
        this.init = function () {
            var self = this;

            self.body = $('body');
            self.window = $(window);
            self.scrollSelector = $('html,body');

            self.setWindowHeight()
                .bindWindowResizeEvent()
                .bindWindowScrollEvent()
                .triggerScrollEvent()
                .addBackToTopCta()
                .bindBackToTopClickEvent();

            return self;
        };

        /**
         * Triggers scroll event.
         * Handy when you enter the page mid-way after following a link with an anchor.
         *
         * @return {backToTop}
         */
        this.triggerScrollEvent = function () {
            var self = this;

            self.window.scroll();

            return self;
        };

        /**
         * Binds the window resize event.
         *
         * @return {backToTop}
         */
        this.bindWindowResizeEvent = function () {
            var self = this;

            self.window.resize(function () {
                self.setWindowHeight()
                    .triggerScrollEvent();
            });

            return self;
        };

        /**
         * Binds the scroll event.
         *
         * @return {backToTop}
         */
        this.bindWindowScrollEvent = function () {
            var self = this;

            self.window.scroll(function () {
                self.fromTop = self.window.scrollTop();

                if (self.fromTop >= self.windowHeight) {
                    self.addScrollClass();
                } else {
                    self.removeScrollClass();
                }
            });

            return self;
        };

        /**
         * Binds the back to top click event.
         * @return {backToTop}
         */
        this.bindBackToTopClickEvent = function () {
            var self = this;

            self.backToTopCta.click(function (e) {
                e.preventDefault();

                self.addAnimateClass()
                    .removeScrollClass()
                    .scrollSelector.animate({scrollTop: 0}, 'slow', function () {
                    self.removeAnimateClass();
                });
            });

            return self;
        };

        /**
         * Adds body class for scrolling.
         *
         * @return {backToTop}
         */
        this.addScrollClass = function () {
            var self = this;

            if (false === self.body.hasClass('scroll-top')) {
                self.body.addClass('scroll-top');
            }

            return self;
        };

        /**
         * Removes body class for scrolling.
         *
         * @return {backToTop}
         */
        this.removeScrollClass = function () {
            var self = this;

            if (self.body.hasClass('scroll-top')) {
                self.body.removeClass('scroll-top');
            }

            return self;
        };

        /**
         * Adds body class for animating.
         *
         * @return {backToTop}
         */
        this.addAnimateClass = function () {
            var self = this;

            if (false === self.body.hasClass('scroll-top-animating')) {
                self.body.addClass('scroll-top-animating');
            }

            return self;
        };

        /**
         * Removes body class for animating.
         *
         * @return {backToTop}
         */
        this.removeAnimateClass = function () {
            var self = this;

            if (self.body.hasClass('scroll-top-animating')) {
                self.body.removeClass('scroll-top-animating');
            }

            return self;
        };

        /**
         * Sets the window height.
         *
         * @return {backToTop}
         */
        this.setWindowHeight = function () {
            var self = this;

            self.windowHeight = self.window.height();

            return self;
        };

        /**
         * Adds the back to top Cta.
         *
         * @return {backToTop}
         */
        this.addBackToTopCta = function () {
            var self = this;

            self.backToTopCta = $('<a/>')
                .attr('title', 'Back to top')
                .attr('href', '#top')
                .addClass('back-to-top_cta')
                .html('Back to top');
            self.body.append(self.backToTopCta);

            return self;
        };
    };

    /**
     * Initiates once the DOM is prepared.
     */
    $(document).ready(function () {
        (new backToTop()).init();
    });
})(jQuery);

Step 2 – Include the file

Include the newly created JavaScript file into your page by pasting the following tag into your code right after your script tag for jQuery, ensuring you change the path to suit your project:

<script type="text/javascript" src="/js/back-to-top.js"></script>

Step 3 – Add the styles for the back to top button

Add the following snippet to your stylesheet:

body {
    position: relative;
}
.back-to-top_cta {
    transition: transform .3s, opacity .3s;
    display: block;
    font-size: 0;
    height: 50px;
    width: 50px;
    border-radius: 50%;
    background: #424242 url(data:image/svg+xml;charset=US-ASCII,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%20standalone%3D%22no%22%3F%3E%0A%3C%21DOCTYPE%20svg%20PUBLIC%20%22-//W3C//DTD%20SVG%201.1//EN%22%20%22http%3A//www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd%22%3E%0A%3Csvg%20width%3D%22100%25%22%20height%3D%22100%25%22%20viewBox%3D%220%200%2042%2026%22%20version%3D%221.1%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20xmlns%3Axlink%3D%22http%3A//www.w3.org/1999/xlink%22%20xml%3Aspace%3D%22preserve%22%20style%3D%22fill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bstroke-linejoin%3Around%3Bstroke-miterlimit%3A1.41421%3B%22%3E%0A%20%20%20%20%3Cg%20transform%3D%22matrix%281.14225%2C0%2C0%2C1.14225%2C-0.702739%2C0.0769231%29%22%3E%0A%20%20%20%20%20%20%20%20%3Cpath%20d%3D%22M19%2C0L37.385%2C18.385L33.142%2C22.627L19%2C8.485L4.858%2C22.627L0.615%2C18.385L19%2C0Z%22%20style%3D%22fill%3Awhite%3B%22/%3E%0A%20%20%20%20%3C/g%3E%0A%3C/svg%3E%0A) no-repeat center 47% / 50% auto;
    position: fixed;
    bottom: 30px;
    right: 30px;
    z-index: 100;
    transform: scale(.8);
    opacity: 0;
}

.back-to-top_cta.scroll-top {
    transform: scale(1);
    opacity: 1;
}

or if you use SASS:

body {
    position: relative;
}
.back-to-top_cta {
    transition: transform .3s, opacity .3s;
    display: block;
    font-size: 0;
    height: 50px;
    width: 50px;
    border-radius: 50%;
    background: #424242 url(data:image/svg+xml;charset=US-ASCII,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%20standalone%3D%22no%22%3F%3E%0A%3C%21DOCTYPE%20svg%20PUBLIC%20%22-//W3C//DTD%20SVG%201.1//EN%22%20%22http%3A//www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd%22%3E%0A%3Csvg%20width%3D%22100%25%22%20height%3D%22100%25%22%20viewBox%3D%220%200%2042%2026%22%20version%3D%221.1%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20xmlns%3Axlink%3D%22http%3A//www.w3.org/1999/xlink%22%20xml%3Aspace%3D%22preserve%22%20style%3D%22fill-rule%3Aevenodd%3Bclip-rule%3Aevenodd%3Bstroke-linejoin%3Around%3Bstroke-miterlimit%3A1.41421%3B%22%3E%0A%20%20%20%20%3Cg%20transform%3D%22matrix%281.14225%2C0%2C0%2C1.14225%2C-0.702739%2C0.0769231%29%22%3E%0A%20%20%20%20%20%20%20%20%3Cpath%20d%3D%22M19%2C0L37.385%2C18.385L33.142%2C22.627L19%2C8.485L4.858%2C22.627L0.615%2C18.385L19%2C0Z%22%20style%3D%22fill%3Awhite%3B%22/%3E%0A%20%20%20%20%3C/g%3E%0A%3C/svg%3E%0A) no-repeat center 47% / 50% auto;
    position: fixed;
    bottom: 30px;
    right: 30px;
    z-index: 100;
    transform: scale(.8);
    opacity: 0;

    .scroll-top & {
        transform: scale(1);
        opacity: 1;
    }
}

You can add this to an existing stylesheet or create a new one, ensuring you link it to your page.

Animating while scrolling

While the page is scrolling to the top, a class is added to the body while the page is scrolling. This allows us to add page animations during the scroll event.

For example, if we wanted the page to go semi-transparent while the page is scrolling, we could achieve this by adding the following CSS rules:

body {
    transition: opacity .3s;
    position: relative;
    opacity: 1;
}

body.scroll-top-animating {
    opacity: .4;
}

Conclusion

Adding a ‘scroll to top’ control has many advantages to the usability of your site. Adding animation improves the feel of quality. Avoiding jQuery animations ensures a fluid experience on both Desktop and Mobile devices.

Feel free to provide feedback in the form of comments by adding them below.

Ste

Web Developer living in Manchester, working for Studio Skylab (http://www.studioskylab.com). Views and thoughts are my own.

You may also like...

2 Responses

  1. James Austin says:

    thnx

Leave a Reply