Skip to content

Instantly share code, notes, and snippets.

@stevoland
Created September 12, 2012 09:48
Show Gist options
  • Save stevoland/3705614 to your computer and use it in GitHub Desktop.
Save stevoland/3705614 to your computer and use it in GitHub Desktop.
jQuery Center in viewport method
/**
* Vertically center an element (popup modal) to the viewport
* If the element is taller than the window height absolute positioning is
* used so that the element will scroll with the docuemnt
*
* @param {boolean} animate Animate to new position or move immediately? Defaults true
* @param {boolean} centerHorizontal Center the element horizontally? Defaults true
* @param {boolean} centerVertical Center the element vertically? Defaults true
*
* @chainable
*/
$.fn.centerInViewport = function (animate, centerHorizontal, centerVertical) {
var POS_ABS = 'absolute',
POS_FIX = 'fixed',
$win = $(window),
offset = this.offset(),
docH = $('body').height();
elH = this.height(),
elW = this.width(),
scrollTop = $win.scrollTop(),
scrollLeft = $win.scrollLeft(),
curLeft = offset.left - scrollLeft,
curTop = offset.top - scrollTop,
elBottom = offset.top + elH,
winH = $win.height(),
winW = $win.width(),
posType = (this.css('position') === POS_FIX) ? POS_FIX : POS_ABS,
newTop = (winH - elH) / 2,
newLeft = Math.max((winW - elW) / 2, 0),
animate = (animate !== false),
centerHorizontal = (centerHorizontal !== false),
centerVertical = (centerVertical !== false);
// El height is greater that viewport height
if (newTop < 0) {
// Make sure the bottom of the element will fit on the page
// otherwise shift it up til it does
newTop = Math.min(docH - elBottom, 0);
// Don't bother repositioning downwards
if (newTop >= curTop) {
centerVertical = false;
}
posType = POS_ABS;
// Allow the element to scroll with the page
this.css({
position: POS_ABS,
top: offset.top + 'px'
});
}
if (!centerVertical) {
newTop = curTop;
}
if (!centerHorizontal) {
newLeft = curLeft;
}
if (posType === POS_ABS) {
newTop += scrollTop;
newLeft += scrollLeft;
}
if (animate) {
this.animate({
top: newTop,
left: newLeft
});
} else {
this.css({
top: newTop + 'px',
left: newLeft + 'px'
});
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment