Centre div in window, in iFrame, from iFrame, without an iFrame ID

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.

6 thoughts on “Centre div in window, in iFrame, from iFrame, without an iFrame ID

  1. I searched how to calculate offset of the parent doc from iframe.
    $(parent.document.documentElement).scrollTop(); helped!

    Thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>