Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
Markdown Monster - The Markdown Editor for Windows

Making Element Position Absolute with jQuery


:P
On this page:

One of the things that I keep running into in library code I create is that I deal with a lot of elements that are floating/dragging or otherwise being moved around the document as free floating elements. jQuery.ui includes a dead simple Draggable plug-in that handles this easily, but in some situations the draggable plug-in is overkill when I simply need to pop up a dialog on the page on top of other content.

One recurring theme for any of these scenarios is that I have to reliably turn an element into absolute positioning and while sometimes it’s as easy as doing $(this).css("position","absolute"); at other times doing this is not enough as the element will ‘jump around’ on the page into another position as it’s popped out of its document containership hierarchy.

After doing this enough times manually and often forgetting one or another setting I added a small plug-in that does it for me now:

$.fn.makeAbsolute = function(rebase) {
    return this.each(function() {
        var el = $(this);
        var pos = el.position();
        el.css({ position: "absolute",
            marginLeft: 0, marginTop: 0,
            top: pos.top, left: pos.left });
        if (rebase)
            el.remove().appendTo("body");
    });
}

If you’re new to jQuery, a plug-in basically extends the jQuery.fn object with a new function that becomes part of the jQuery matched set. The function can be called just like any other jQuery function that operates on the matched set of elements. The function is called in the context of the matched set object – so this is the jQuery instance of all the matched elements. Note that use return this.each() {} to iterate of each of the matched items and return the matched set as a result of the call. This ensures that this function can be used in the call chain of jQuery commands against the matched set and further functions can be called after it.

The plug-in code makes the element absolutely positioned as well as removing margins and explicitly forcing the top and left properties to be set. Removing the margin ensures you don’t get any funky bumping of content that is effectively  out of the flow of the document – an important aspect if you’re moving things around say with drag operations or else you end up with really odd offsets. Setting top and left shouldn’t be necessary usually but in some situations where elements are nested deeply inside of other elements the default position will cause elements to be thrown into unexpected page positions. jQuery’s position() function looks at a variety of properties for placement of elements and generally reliable in getting the correct location and explicitly assigning it.

The rebase parameter when set causes the element to be removed from its current document position and instead be attached to the body element. This can be useful in some instances where elements are deeply nested when the container positioning and margins can cause erratic behavior for positioning. For example, I just ran into a situation with an element that was loaded inside of a <fieldset> element and no matter what I tried the absolute position – and the event object offsets that mouse events caused where completely off. Rebasing to the body of the document made this same element work just fine. This option should be avoided if possible as it causes the element to be basically cloned which means any references to the old element become invalid. Rebasing can also cause problems with CSS Selectors both for CSS or jQuery if the element depends on the document hierarchy to be found.

It’s useful – just gone through my library routines and remove about 10 instances where similar code was in use and replaced with this. Maybe some of you may find this useful or give you some ideas on how to get elements absolutely positioned.

Posted in jQuery  

The Voices of Reason


 

William Kapke
October 21, 2008

# re: Making Element Position Absolute with jQuery

Very cool. At minimum, this has was helpful in that I had one of those 'hit my forehead' moments when I realized that I could just be giving an object to .css() rather than calling it once for each property... DUH! (yep, I've only been using Jquery for a few weeks)

..sometimes I skim over the wrong things. Sigh. :)

THanks!

Jason
October 22, 2008

# re: Making Element Position Absolute with jQuery

Instead of:

top: pos.left, left: pos.left

did you mean:

top: pos.top, left: pos.left // pos.TOP

Rick Strahl
October 22, 2008

# re: Making Element Position Absolute with jQuery

@Jason, fat fingers. Thanks fixed. Not sure how that happened. I must have made some manual changes last night as I was posting this because the code in my source files has the right setup. Odd.

Fixed in the article above.

David Fauber
October 28, 2008

# re: Making Element Position Absolute with jQuery

I'm pretty sure the Dimensions plugin offers similar functionality as well.

Keep up the good work, enjoy the jq stuff.

Robert Brewer
February 26, 2009

# re: Making Element Position Absolute with jQuery

Thanks! If you're going to set marginTop/Left, you should probably subtract any existing values:

               top: pos.top - this.style.marginTop,
               left: pos.left - this.style.marginLeft,
               marginTop: 0, marginLeft: 0

Johnny
August 12, 2010

# re: Making Element Position Absolute with jQuery

The code was great. I really liked the word 'containership' too, lol.

jay
January 13, 2011

# re: Making Element Position Absolute with jQuery

how can i get or set the div position(left,right,top,bottom) using jquery?

Rick Strahl
January 13, 2011

# re: Making Element Position Absolute with jQuery

@jay - use .css({ left: x, top: y, bottom: bott, right: right });

Steve
September 01, 2011

# re: Making Element Position Absolute with jQuery

Awesome! I was battling this exact thing where the div would jump around as it was being repositioned. This (explicitly setting the top, left via CSS) did the trick! You da man Rick. Thanks.

Marco
September 23, 2011

# re: Making Element Position Absolute with jQuery

I'm not sure calling remove() is needed: appendTo() should already remove it beforehand.

john
September 29, 2013

# re: Making Element Position Absolute with jQuery

How do you actually implement this on something? I am new and would like to use this code

Rick Strahl
September 30, 2013

# re: Making Element Position Absolute with jQuery

@John - it's a jQuery function so make sure the jquery script is loaded on the page as well as this function extension on the page. Then:

$("#SomeElement").makeAbsolute();

Alex K.
December 27, 2013

# re: Making Element Position Absolute with jQuery

Just for the case, you want to use it for multiple elements on a page which were positioned as inline-block before:

$.fn.makeAbsolute = function(rebase) {
return $(this.get().reverse()).each(function() {
el = $(this);
pos = el.position();
el.css({ position: "absolute",
marginLeft: 0, marginTop: 0,
top: pos.top, left: pos.left });
if (rebase)
el.remove().appendTo("body");
alert("99");
});
}

A simple direction-change did the trick.

Regards and thanks for the code!

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024