How to create a fixed / sticky sidebar in CSS / JS?

23,209

Solution 1

I don't like heavy JS solutions, so important thing to ask is - preferred compatibility. In IE8+ it is possible instead of

var $window = $(window),
    $sidebar = $(sidebar);

$window.on('resize', function(){
    $sidebar.height($window.innerHeight());
});

$window.resize();

do something like this (pure CSS solution):

#sidebar {
    position: fixed;
    left: 0; /* or right */
    top: 0;
    bottom: 0;
    overflow: auto;
}

When you have top&bottom / left&right value at the same time, box will be stretched. (JSFiddle demo)

Solution 2

Got it. It is Javascript based, but I'm sure that's nothing heavy and even IE8 should solve it pretty fine.

var top = $('#sidebar').offset().top;
var height = $('#sidebar').height();
var winHeight = $(window).height();
var gap = 10;
$(window).scroll(function(event) {
    var scrollTop = $(this).scrollTop();

    // sidebar reached the (end - viewport height)
    if (scrollTop + winHeight >= top + height + gap) {
        // if so, fix the sidebar and make sure that offset().top will not give us results which would cancel the fixation
        $('#sidebar').addClass('fixed').css('top', winHeight - height - gap + 'px');
    } else {
        // otherwise remove it
        $('#sidebar').removeClass('fixed').css('top', '0px');
    }
});​

demo

Solution 3

You could catch client window's height and giving it to your sidebar like this :

var sidebarHeight = $(window).innerHeight();

$('#sidebar')​​​​​​​​​​​.css('height',sidebarHeight);​​​​​​​​​​​​​

With the proper CSS for the sidebar :

#sidebar {
    position: fixed;
    right: 0;
    top: 0;
    width: 200px;
    overflow: hidden;
}

Here is a working JSFiddle.

You could also watch for window resizing to avoid a mess on resize :) Here is the way to go with jQuery

Good luck

Solution 4

Not sure if you have this figured out but I have created a contained sticky sidebar jQuery plugin. It's really simple and allows you to invoke with just one line of jQuery. Take a look here: http://mojotech.github.com/stickymojo/

It starts by position: fixed; then uses javascript to handle any resizes, scrolls and even allows you to specify a footer element that it should not intersect. By combining these approaches you will get a smooth looking fixed element. Plus, we made it easy for you.

Share:
23,209
Borek Bernard
Author by

Borek Bernard

For the past few years, I've been trying to bring Git version control to WordPress via a project called VersionPress. We're also working on a cloud-hosted version, VersionPress.com. I love TypeScript, Node.js, Kubernetes and clean code.

Updated on July 15, 2022

Comments

  • Borek Bernard
    Borek Bernard almost 2 years

    I'm trying to create a website with main content area and a sidebar, something like here on Stack Overflow. The goal is that when you scroll down, the sidebar stays visible.

    I have seen two approaches to this:

    1. position:fixed;
    2. JavaScript manipulation with the DOM

    Approach no. 1, as far as I know, will have a problem when the viewport is smaller than the sidebar contents so I guess that can't be used reliably and JavaScript scripts that I have seen are usually animated or generally "slow" (you can see that there is redrawing going on after each scroll).

    Can someone point out a JavScript library / CSS approach that would not suffer from the aforementioned issues?

    Edit: an example would be this page but with the sidebar sticking to the top without an animation and correctly handling the situation when the sidebar is higher than content / viewport.

  • Chango
    Chango over 12 years
    I also recommend reading something about css3 media query, just in case. Here is an excellent article about that: webdesignerwall.com/tutorials/responsive-design-in-3-steps
  • Borek Bernard
    Borek Bernard over 12 years
    This solution suffers from issue 1 too, i.e., when the sidebar is higher than page contents and viewport, some of its contents is inaccessible.
  • Borek Bernard
    Borek Bernard over 12 years
    Thanks, this is certainly better than not being able to access the sidebar contents at all but is there a solution that would use the main scrollbar and not add a specialized one just for the sidebar? Like, for example, if on this page jsfiddle.net/h9XEc/1 the scrollbar was at the right of the result frame, not in the sidebar.
  • Borek Bernard
    Borek Bernard almost 12 years
    Try making your browser 50px high. How do you access the download button in your sidebar?