2

I have a "fixed" menu bar on the left side of a website that I want to follow the scrollbar down the page when the user scrolls. I've tried two approaches so far, one css, and one jquery:

1) My first attempt was to use css style fixing:

#leftframe {
 position:fixed;
 width: 200;
}   

Normally, this works great on vertical scrolling. The problem with this solution is that when the window isn't very wide, and the user tries to scroll, it goes right over the page contents.

2) After some research, I found that there's a jquery approach that allows you to fix an element in one direction, as described on stack overflow here: CSS: fixed position on x-axis but not y?

Using the approach outlined there, I wrote this nice little function to do it for me:

function float_vertical_scroll(id) {
    $(window).scroll(function(){
        $(id).css({
            'top': $(this).scrollTop() //Use it later
        });
    });
}

Only, now the problem is, I've tried this in Chrome and Safari, and both show a noticeable flicker of the menu bar during vertical scrolling. The menu moves in a very "choppy" fashion, where the css solution smoothly slid it down the page.

Does anyone know why the jquery solution is so choppy, and if anything can be done about it? Is there some third solution that will give me the "best of both worlds"?

Thanks everyone.

Community
  • 1
  • 1
jsarma
  • 1,344
  • 11
  • 19
  • 1
    The jQuery solution is choppy because you scroll faster than JavaScript can update the element. The CSS solution is done by the browser and saves time by bypassing the JS entirely. – Blazemonger Apr 25 '13 at 19:31
  • True. I guess css needs to be updated to have fixed in one direction. – jsarma Apr 25 '13 at 19:51
  • You could use [this question's answers](http://stackoverflow.com/q/14035083/901048) and have the element moved only when scrolling stops, instead of whenever scrolling happens. – Blazemonger Apr 25 '13 at 20:04

1 Answers1

3

I think I just came up with a great solution for this problem, so I'm going to post it here in case others are also looking for something.

To recap, my problem was that I wanted a left menu to be fixed vertically, so it follows the vertical scroll, but not fixed horizontally. css only allows fixing in both directions. So with the css solution, when the window was small, a horizontal scrollbar would appear, and when used, it would cause the menu to float over the page content.

The float_vertical_scroll function which I presented as another solution in the initial question had the flaw that when you scrolled vertically, javascript would refresh too slowly, causing the menu bar to move in a jumpy, choppy fashion. That solution set the position to absolute, and relied on jquery to move the menu down on every scroll event.

The thing about sidebar menus on most pages is that 99% of scrolling is vertical. Very little is horizontal. So I thought, what if we could make the horizontal scrolling choppy, and the vertical scrolling smooth?

That led to the solution below. Instead of setting the frame to absolute and scrolling it vertically in javascript, I've set it to fixed, and reversed the offset on horizontal scrolling. This cancels out the horizontal scrolling. Horizontal scrolling might be a bit jumpy, but no one really cares because it's rarely used:

function float_horizontal_scroll(id) {
    jQuery(window).scroll(function(){
        jQuery(id).css({
            'left': 0 - jQuery(this).scrollLeft()
        });
    });
}

#leftframe {
 position:fixed;
 width: 200;
}   
jsarma
  • 1,344
  • 11
  • 19