Thu. February 26, 9:42:40 AM
Great work. When I shrink the browser window to be shorter than the centered div I'm unable to scroll to the top of the div. Is there a way to correct this? Thanks.
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.
#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.
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?
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);
<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.
Great work. When I shrink the browser window to be shorter than the centered div I'm unable to scroll to the top of the div. Is there a way to correct this? Thanks.
I've disliked the css solutions for the same reason. Great idea automating it in jQuery and great solution!
@Trygve: Add vAlign and hAlign calls to documents resize-Event? This can be done by jQuery, too...
@Trygve I think this documentation might help you with your resize problem: JQuery Events Resize
Beautiful. I've used this site http://www.emblematiq.com/blog/vertical_align_with_css/ for veritcal align reference but it get really messy with Step 3 — Multiple lines vertical-align:middle.
You're getting me more and more interested in jQuery. I'll probably start using it on my site to force myself to learn it.
@Eric, yes I've joined the dark side of javascript libraries finally! I don't know why but I seem to be enjoying JQuery a lot. I especially like using some of the advanced selectors that I can't pull of in CSS (In IE anyway). I also like how it has a bunch of plugins you can use, as this keeps the frameworks overall file size smaller. You were always right, the frameworks allow you to actually enjoy javascript for once.
Just curious, do you host your libraries with google, or do you rock them locally?
Have you ever looked at this: http://code.google.com/p/ie7-js/
I use Google's server for my JQuery library - http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js. I know Google also has a javascript variant that loads that same file but I prefer the good ol' fashioned way via the script tag. I've seen Dean Edwards IE7.js file before (I follow his blog). I tried IE7.js for a project but it was causing me a lot of grief over some specific IE CSS bugs so I had to scrap it.
Here's a compact version
I removed the formula because (Height + (OuterHeight - Height)) === OuterHeight
$.fn.extend({
vAlign: function(){
var oh=$(this).outerHeight();
return $(this).css({position: 'absolute', marginLeft: (-1*(oh/2))+'px',top: '50%'});
},
hAlign: function(){
var ow=$(this).outerWidth();
return $(this).css({position:'absolute', marginTop: (-1*(ow/2))+'px', left: '50%'});
}
});
Great work Neal!!!
Thanks for the code, I changed it a bit to have a minimum position from the top the window, because I wanted content to start at the vertical center of a page, but if the window height is smaller it should stay at 250px from top.
Now the code looks like this, I commented it for explanation:
(function (jQuery) {
jQuery.fn.vAlign = function() {
return this.each(function(i){
var pct = 50; // vertical alignment percentage
jQuery(this).css("top", pct + "%"); // Reset position to standard
var md = 250; // minimum position in pixels from top
var ctr = 0; // 0: start content from middle // 1: center content in the middle
var h = jQuery(this).height();
var oh = jQuery(this).outerHeight();
var mt = (h + (oh - h)) / 2;
var os = jQuery(this).position();
if (ctr == 1) {
jQuery(this).css("margin-top", "-" + mt + "px");
var md = md + mt;
}
if (os.top > md) {
jQuery(this).css("top", pct + "%");
} else {
jQuery(this).css("top", md + "px");
}
jQuery(this).css("position", "absolute");
});
};
})(jQuery);
To initiate use:
jQuery(document).ready(function() {
jQuery("#container").vAlign();
});
jQuery(window).resize(function() {
jQuery("#container").vAlign();
});
Works for me in FF, will check IE soon.
Site Coded And Designed By Neal Grosskopf Using No Crappy CMS Or Themes