I recently read an article showing 5 way to vertically align elements using CSS. I thought that the author showed some great examples of how to accomplish this. My only complaint is many of the examples were somewhat hacky or required that you set a height on the DIV you want to vertically align. Also a few of them did not work in IE6 or IE7. I set out to create a solution that did not require the height of the DIV to be known and would work in both IE6 and IE7.
My JQuery code is based on the following CSS:
#content
{
position: absolute;
top: 50%;
height: 300px;
margin-top: -150px;
width: 300px;
margin-left: -150px;
}
I decided that much of this is redundant and makes too many assumptions about our content. If the amount of content were to grow larger, we would have to update the CSS each time. On most dynamic websites this is not a feasible solution. Also the margin-top and margin-left were to always be exactly half of the height/width so it seemed silly to have to do that math each time the width or height were to change.
Vertical Align JQuery Plugin
I first decided that I would use JQuery to figure out the height of the DIV and the content within it. I then had to take into consideration that the DIV may have a border or padding so I used JQuery's .outerHeight() property to get that value. The resulting formula looks like this:
(Height + (OuterHeight - Height)) / 2
I took that formula/code and made it so it can be used like a JQuery plugin:
(function ($) {
$.fn.vAlign = function() {
return this.each(function(i){
var h = $(this).height();
var oh = $(this).outerHeight();
var mt = (h + (oh - h)) / 2;
$(this).css("margin-top", "-" + mt + "px");
$(this).css("top", "50%");
$(this).css("position", "absolute");
});
};
})(jQuery);
This can be called when our DOM is fully loaded like so:
$(document).ready(function() {
$("#content").vAlign();
});
Simple, isn't it?
Horizontal Align JQuery Plugin
I also created a similar plugin to horizontally align a DIV. By combining the vertical align and horizontal align plugins we can set a DIV in the exact middle of the viewport. I realize that this is usually solved by giving our DIV a width and setting it's margin to 'auto'. The problem was my DIV was already positioned absolute so setting the margin to 'auto' wasn't working. I therefore used a similar approach to my vertical align solution.
(function ($) {
$.fn.hAlign = function() {
return this.each(function(i){
var w = $(this).width();
var ow = $(this).outerWidth();
var ml = (w + (ow - w)) / 2;
$(this).css("margin-left", "-" + ml + "px");
$(this).css("left", "50%");
$(this).css("position", "absolute");
});
};
})(jQuery);
Putting It All Together
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"></script>
<script type="text/javascript">
(function ($) {
$.fn.vAlign = function() {
return this.each(function(i){
var h = $(this).height();
var oh = $(this).outerHeight();
var mt = (h + (oh - h)) / 2;
$(this).css("margin-top", "-" + mt + "px");
$(this).css("top", "50%");
$(this).css("position", "absolute");
});
};
})(jQuery);
(function ($) {
$.fn.hAlign = function() {
return this.each(function(i){
var w = $(this).width();
var ow = $(this).outerWidth();
var ml = (w + (ow - w)) / 2;
$(this).css("margin-left", "-" + ml + "px");
$(this).css("left", "50%");
$(this).css("position", "absolute");
});
};
})(jQuery);
$(document).ready(function() {
$("#content").vAlign();
$("#content").hAlign();
});
</script>
<style type="text/css">
#content { width: 400px; }
</style>
<div id="content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas eu dui eget nulla condimentum gravida. Vivamus erat leo, ultricies quis, gravida a, fringilla eu, urna. Pellentesque a mauris ac nisl semper egestas. Pellentesque ut elit in pede mattis gravida. Donec ac lectus a nisi suscipit placerat. Maecenas quis ipsum. Pellentesque mattis tellus. Suspendisse sollicitudin accumsan tortor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed metus. Quisque et leo at erat rutrum lobortis. In tempus lectus eget ligula convallis tristique.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas eu dui eget nulla condimentum gravida. Vivamus erat leo, ultricies quis, gravida a, fringilla eu, urna. Pellentesque a mauris ac nisl semper egestas. Pellentesque ut elit in pede mattis gravida. Donec ac lectus a nisi suscipit placerat. Maecenas quis ipsum. Pellentesque mattis tellus. Suspendisse sollicitudin accumsan tortor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Sed metus. Quisque et leo at erat rutrum lobortis. In tempus lectus eget ligula convallis tristique.
</div>
I should point out that the only CSS property you will need to set on the DIV is it's width. If you want your DIV's width to be 100% you can remove this property.