7

It's easy to keep a column in my layout fixed so it's always visible, even when the user scrolls down.

It's also easy to only move the column down the page when the page is scrolled down far enough for it to be out of the viewport so it's anchored before scrolling starts.

My problem is, I have left hand column that is taller than the average window so you need to be able to scroll down to see all the content (controls) in the left column but at the same time when you scroll up you want to see the top of the controls again.

Here's a visual of what I want to accomplish: enter image description here

So the left column is always occupying 100% of the height of the window but as the user scrolls down they can see the bottom of the div, and when they start to scroll up the scrolls up until it reaches the top of the window again. So no matter how far they scroll the page, the top of the div is always nearby.

Is there some jQuery magic to make this happen?

powlette
  • 1,800
  • 20
  • 41
  • might i suggest you look into twitter bootstrap, it can solve this with little to no effort. – abc123 Jul 10 '13 at 13:35
  • 2
    @abc123: Really? Reference? – Ry- Jul 10 '13 at 13:36
  • I'm familiar with bootstrap, but I don't recall seeing this in action. Can you point me to a page where they show this? – powlette Jul 10 '13 at 13:36
  • 1
    abc123 thinks Bootstrap's Affix plugin can do this, but it can't - it will only stick an element to the page if it goes above the viewport. I don't know of any plugins that will do what you want (which is a very nice effect), so you'll likely have to do it yourself – Bojangles Jul 10 '13 at 13:39
  • @minitech As bojangles has pointed out I thought the Affix plugin could do this upon further research I was mistaken. Since this is now gone 4 comments deep I will not be deleting mine as to keep a clear comment history for this post. – abc123 Jul 10 '13 at 13:44

3 Answers3

2

Did you mean something like this? (Demo)

var sidebar = document.getElementById('sidebar');
var sidebarScroll = 0;
var lastScroll = 0;
var topMargin = sidebar.offsetTop;

sidebar.style.bottom = 'auto';

function update() {
    var delta = window.scrollY - lastScroll;
    sidebarScroll += delta;
    lastScroll = window.scrollY;

    if(sidebarScroll < 0) {
        sidebarScroll = 0;
    } else if(sidebarScroll > sidebar.scrollHeight - window.innerHeight + topMargin * 2) {
        sidebarScroll = sidebar.scrollHeight - window.innerHeight + topMargin * 2;
    }

    sidebar.style.marginTop = -sidebarScroll + 'px';
}

document.addEventListener('scroll', update);
window.addEventListener('resize', update);
#sidebar {
    background-color: #003;
    bottom: 1em;
    color: white;
    left: 1%;
    overflow: auto;
    padding: 1em;
    position: fixed;
    right: 80%;
    top: 1em;
}

body {
    line-height: 1.6;
    margin: 1em;
    margin-left: 21%;
}

It almost degrades gracefully, too…

Ry-
  • 218,210
  • 55
  • 464
  • 476
1

I made a fiddle for you, hope this helps you out abit. I detect scroll up or scroll down, and set the fixed position accordion to the direction.

http://jsfiddle.net/8eruY/

CSS

aside {
    position:fixed;
    height:140%;
    background-color:red;
    width:100px;
    top:20px;
    left:20px;

}

Javascript

//Detect user scroll down or scroll up in jQuery

var mousewheelevt = (/Firefox/i.test(navigator.userAgent)) ? "DOMMouseScroll" : "mousewheel" //FF doesn't recognize mousewheel as of FF3.x
$('html').bind(mousewheelevt, function(e){

    var evt = window.event || e //equalize event object     
    evt = evt.originalEvent ? evt.originalEvent : evt; //convert to originalEvent if possible               
    var delta = evt.detail ? evt.detail*(-40) : evt.wheelDelta //check for detail first, because it is used by Opera and FF

    if(delta > 0) {
        $('aside').css('top', '20px');
        $('aside').css('bottom', 'auto');
    }
    else{
        $('aside').css('bottom', '20px');
        $('aside').css('top', 'auto');
    }   
});
Community
  • 1
  • 1
koningdavid
  • 7,903
  • 7
  • 35
  • 46
0

http://jsfiddle.net/KCrFe/

or this:

.top-aligned {
    position: fixed;
    top: 10px;
}

with

var scrollPos
$(window).scroll(function(event){
    var pos = $(this).scrollTop();

    if ( pos < scrollPos){
        $('.sidebar').addClass('top-aligned');
    } else {
        $('.sidebar').removeClass('top-aligned');
    }

    scrollPos = pos;
});
Dom Day
  • 2,542
  • 13
  • 12