Update: This code has been replaced.
Centring a div is not so hard. Centring a div on a window regardless of the windows scroll position is a little harder. Centring a div in the viewport in an iFrame that is full height (i.e. does not scroll) in a window that does scroll when that window is scrolled and you do not know the ID of the iFrame is a bit of a pain in the arse. So I record it here, in case it helps anyone. This function accepts a jQuery object as its only argument.
function centerIt($el) { var frm = $('iframe',top.document.body); var iframeXOffset = 0, iframeYOffset = 0, windowHeight = 0, windowWidth = 0; var i=frm.length; while (i--) { if (frm[i].contentDocument) { doc = frm[i].contentDocument; } else { doc = frm[i].contentWindow.document; } if (doc === document) { //located our iframe! iframeXOffset = $(frm[i]).offset().left; iframeYOffset = $(frm[i]).offset().top; break; } }; if (jQuery.browser.msie) { windowWidth = top.window.document.documentElement.clientWidth; windowHeight = top.window.document.documentElement.clientHeight; } else { windowWidth = top.window.innerWidth; windowHeight = top.window.innerHeight; } var elHeight = $el.height(); var newTop = ((windowHeight/2) - (elHeight/2)) - iframeYOffset + $(parent.document.documentElement).scrollTop(); if ((newTop + elHeight) > $(document).height()) { newTop = $(document).height() - elHeight; } $el.css ({ left: ((windowWidth/2) - ($el.width()/2)) - iframeXOffset + $(parent.document.documentElement).scrollLeft(), top: newTop }); }
Of course, this makes much more sense as a jQuery chainable plug-in:
/****************************************************************** Name: center Description: Center a div on page, even in an iframe Author: AK (www.zeroedandnoughted.com) Date: 8th Jan 2009 Version: 0.1 Dependencies: jQuery Notes: ******************************************************************/ (function($) { $.fn.center = function() { return this.each(function() { var $this = $(this) var frm = $('iframe',top.document.body); var iframeXOffset = 0, iframeYOffset = 0, windowHeight = 0, windowWidth = 0; var i=frm.length; while (i--) { if (frm[i].contentDocument) { doc = frm[i].contentDocument; } else { doc = frm[i].contentWindow.document; } if (doc === document) { //located our iframe! iframeXOffset = $(frm[i]).offset().left; iframeYOffset = $(frm[i]).offset().top; break; } }; if (jQuery.browser.msie) { windowWidth = top.window.document.documentElement.clientWidth; windowHeight = top.window.document.documentElement.clientHeight; } else { windowWidth = top.window.innerWidth; windowHeight = top.window.innerHeight; } var elHeight = $this.height(); var newTop = ((windowHeight/2) - (elHeight/2)) - iframeYOffset + $(parent.document.documentElement).scrollTop(); if ((newTop + elHeight) > $(document).height()) { newTop = $(document).height() - elHeight; } $this.css ({ left: ((windowWidth/2) - ($this.width()/2)) - iframeXOffset + $(parent.document.documentElement).scrollLeft(), top: newTop }); }); }; })(jQuery);
Yes, I’m British. But yes, I spelt it “center”. I hate inconsistency worse than bastardised spelling. Comments welcomed, as always.
Update: It was possible, if you resized the frame, to get the centred box to appear off-screen. This has been fixed.