CSS: Position-x and Position-y

While building out a content management system for DMP I needed to create a toolbar which would stay with position: fixed; on the y-axis, but act like position: absolute on the x-axis. To achieve this I used a clever JavaScript class from David Walsh called scrollspy.

Position-x: Position-y:

View Demo

The JavaScript

Things you will need first: Mootools (This demo uses 1.2.4) and the ScrollSpy plugin from David Walsh. Next write this for you element:

var ss = new ScrollSpy({
     mode: 'horizontal',
     onTick: function(position,state,enters,leaves) {
          $("sidePanel").style.left = -position.x+"px";
     },
     container: window
});

The CSS

In the CSS use position: fixed; because we have handled the position-x: absolute; in JavaScript. so:

#sidePanel {
     position:fixed;
     left:0;
     top:0;
     width:250px;
     z-index:1000;
}

The above example will keep our sidePanel element from disappearing when you scroll down the page but it will scroll with the page when the user scrolls right.

To do the opposite ie. position-x: fixed; position-y: absolute; In the JavaScript change mode: ‘horizontal’ to mode: ‘vertical’ and -position.x+”px”; to -position.y+”px”; and that’s it any comments, ideas or improvements leave them below.

32 Responses :)
  1. Thanks alot, this quick tutorial saved my day! (:

  2. Hey man no worries.

    I’ve used this code so many time (^_^)

  3. Hey Ricky,

    I found this tutorial while searching how to have a fixed sidebar vertically but not horizontally, like the sidePanel you have on this site.

    I’ve run into one problem that I can’t seem to figure out though. Everything works perfectly, the x-axis is position:absolute and the y-axis is fixed, but when I make the window small enough to scroll horizontally, and scroll so that the sidebar is out of the screen, and then maximize the window, the sidebar is still out of the screen (now with no horizontal scroll).

    This website here doesn’t do that, everything pops right back into place when I maximize here, so I was wondering if you could tell me how to fix that.

    Thanks a bunch.

  4. Hi Ricky!

    I get an error in the console, telling me style.left is undefined. wtf?

  5. In my demo or your own? Cos I can’t replicate the error here. (firefox/firebug).

  6. Thank you very much!

  7. I *love* this demo, but I’m having trouble getting it to work. I’m pretty good with html and css, but I have no javascript experience. I can’t even figure out if I’m supposed to put MooTools and ScrollSpy in the head, in the body, or in a linked file! Could you point me to a dummies guide on how to use this awesome stuff?
    Thanks,
    Meg :)

  8. Hi Meg,
    David Walsh has updated his plugin for a newer version of mootools. I used this version of scroll spy:

  9. var ScrollSpy = new Class({

    /* implements */
    Implements: [Options,Events],

    /* options */
    options: {
    min: 0,
    mode: ‘vertical’,
    max: 0,
    container: window,
    onEnter: $empty,
    onLeave: $empty,
    onTick: $empty
    },

    /* initialization */
    initialize: function(options) {
    /* set options */
    this.setOptions(options);
    this.container = $(this.options.container);
    this.enters = this.leaves = 0;
    this.max = this.options.max;

    /* fix max */
    if(this.max == 0)
    {
    var ss = this.container.getScrollSize();
    this.max = this.options.mode == ‘vertical’ ? ss.y : ss.x;
    }
    /* make it happen */
    this.addListener();
    },

    /* a method that does whatever you want */
    addListener: function() {
    /* state trackers */
    this.inside = false;
    this.container.addEvent(‘scroll’,function() {
    /* if it has reached the level */
    var position = this.container.getScroll();
    var xy = this.options.mode == ‘vertical’ ? position.y : position.x;
    /* if we reach the minimum and are still below the max… */
    if(xy >= this.options.min && xy <= this.max) {
    /* trigger Enter event if necessary */
    if(!this.inside) {
    /* record as inside */
    this.inside = true;
    this.enters++;
    /* fire enter event */
    this.fireEvent(‘enter’,[position,this.enters]);
    }
    /* trigger the “tick”, always */
    this.fireEvent(‘tick’,[position,this.inside,this.enters,this.leaves]);
    }
    else {
    /* trigger leave */
    if(this.inside)
    {
    this.inside = false;
    this.leaves++;
    this.fireEvent(‘leave’,[position,this.leaves]);
    }
    }
    }.bind(this));
    }
    });

  10. Hey Ricky,

    The demo you have is awesome, but I cannot get it to work. I’ve copied the javascript you posted in the earlier comment, saved it as ScrollSpy.js, and still nothing. I also tried copying the source of your demo example and using that, but that doesn’t work either. I’d really like to get this working because it seems like easily the best fix anywhere on the internet that I can find.

    Basically what I’d like to know is this: What isn’t displayed in the source of the demo page? I feel like thats probably the key to whatever I have that isn’t working.

  11. As an update, I figured out what my problem was. The jquery library does not seem to play nicely with mootools, so ensure that you’re not including both if you want to avoid an hour of frustration.

  12. Great tutorial, thanks! :)

  13. Sorry man your demo is cool but your explaination is defintely too brief and lacks of some fundamental details; your code in demoMain is quite different, that’s why the demo works!

  14. Oh man I should have looked for this years ago! Thanks for the knowledge!

  15. Looks great and is exactly the problem I would like to solve, i.e. fixed x and absolute y pos., but I am not experienced enough to use your code. I want to scroll a widget element in WP Theme Weaver. Any directions how and whether your solution can be applied are very much appreciated.

  16. tatarao mylipalli

    Hi Ricky,
    The demo is so nice and its working fine in IE browser and the events of rad grid control also fired, but in firefox and chrome rad grid control events are not fired. please suggest me is their any modification to work in firefox and chrome.
    Thanks.

  17. This looks nice – but as my project is depending on jQuery: Is there an alternative method without Mootools?

  18. I’m trying to integrate with jQuery, I’ve tried 1.4 w/out luck. When I link the jQuery Lib none move in the allowed direction. Do you know if this is compatible with other versions of jQuery?

    Thanks
    PD

  19. Nem acreditei quando vi rsrs…

  20. [how i can put the position 20px from right using css to manage my background image. layout type is flexible and div in which i want to give position is also on 100%.]

    Add 20px transparent space on the right of your image.
    Then set the background-position : right top
    Or so ..

  21. This is Exactly what I want to use in My website…
    But I could not get this working for me….

    Kindly provide step-by-step explaination for How to Use Your scripts …….

  22. For compatibility with jQuery, read this:
    http://docs.jquery.com/Using_jQuery_with_Other_Libraries

    TL;DR:
    Add

    var $j = jQuery.noConflict();

    to your head section and change $ to $j (or $whatever-you want-to-call-it) accordingly in scripts relying on jQuery. If you don’t want to/can’t change from $ to $j, there are some other methods described in the link.

  23. Such a great tutorial! Exactly what I was looking to do.

    Just one question…

    When this is running on an iPhone/iPad the scroll is ‘jumpy’ in relation to the content of the page. The main content scrolls smoothly then my fixed header, footer and logo snap into place a moment later. Any ideas on how to get around this?

    …..or is this just an issue with the iOS reading the javascript?

    Cheers

    MM

  24. Hi Michael,

    I still don’t fully understand IOS’s scroll characteristics. First they had no fixed content and now it seams to work but as you say it jumps. It’s the first time I looked at this example in IOS but I imagine it’s down to the JS onscroll event not triggering in IOS.

  25. If you’re using jQuery, this alternative to David Walsh’s Scrollspy worked for me:

    https://github.com/sxalexander/jquery-scrollspy

  26. Thank you for your great tutorial!!! I do finally solve my problem. Thank you so much!!

  27. Could anybody tell me what would be wrong with a much easier solution I just fiddled out (I am a programming noob):

    window.addEvent(‘scroll’, function(){
    $(“sidePanel”).setStyle(‘left’, -Window.getScrollLeft()+’px’);
    });

    or will this make problems in IOS?

    http://jsfiddle.net/Q4dWz/178/

  28. Thnx 4 this grt tutrl and demos….. it is really nice. i have been lookn 4 it. thnx

  29. hi
    has this been fixed. i tried to do it but i ididnt work.

  30. Hi !

    I wrote a dragdrop function that works fine, with ‘absolute’ positionned element. Now, I’d like to dragdrop an element that is static, at first !

    The issue is that when I put it to ‘absolute’, the element suddenly changes its position on the page. How could I fix this issue ?

    Thanx a lot !

  31. I have another variant how to do fixed Position-x. My variant needs only css and js. You can see it on my website http://amanda.org.ua/view.html?p=pos

  32. Hi
    This is just what I need.
    I have looked at the demo, viewed the source code, cut and paste this into Coda but it doesn’t work, the background scrolls and the three panels stay fixed. What am I doing wrong?

Leave a Comment