
Sometimes you may want to vertically align a block item, but the CSS-only vertical aligning methods don’t make you feel clean. Personally, I hate having to style items as a table/table cell to get them to vertically align in Internet Explorer.
jQuery to the rescue. Using a jQuery vertical align snippet as my base code, I modified it to be a jQuery plugin that will allow you to use the function in the jQuery chain.
jQuery Vertical Align Plugin Code
Simply copy this code into your website (if you don’t know where, leave a comment):
(function ($) {
// VERTICALLY ALIGN FUNCTION
$.fn.vAlign = function() {
return this.each(function(i){
var ah = $(this).height();
var ph = $(this).parent().height();
var mh = (ph - ah) / 2;
$(this).css('margin-top', mh);
});
};
})(jQuery);
Now, you can use vAlign as you wish; ie: $('#example p').vAlign();.
Did this make your life easier? Was this information worth a buck?
Donate with PayPal (Much appreciated!)
If it’s not working
If it’s not working, it may be because the script applies a margin to the element, which may not work in all situations. Try changing 'margin-top' to 'padding-top' and see if that helps.
Any questions or comments?
Related posts:
Katz Web Services is a
{ 2 trackbacks }
{ 38 comments… read them below or add one }
Very usefull love it keep up the good work.
Does it work on multiple instances? So far, I can only get it to vAlign on the first named element.
Thanks.
@Jonas – I’ve not had any issues with multiple instances. You may want to try the
.each()function and see if that helps.Thanks Zack. I have a sillier question: do you know if there is any way to get it to work if the html section it is applied to is hidden by default on page load and only visible if the user makes it so?
Nevermind. I’ll just fire the .each() for the show and hide. Thanks again.
Thanks for the code! The code however doesn’t run for each element in the selector. I updated it to fix this issues, here it is:
return this.each(function() {
var ah = $(this).height();
var ph = $(this).parent().height();
var mh = (ph – ah) / 2;
$(this).css(‘margin-top’, mh);
});
Hey Ryan,
Sorry about that – I thought it was working properly. I’ve updated the code in the article. Thanks!
Hi,
could you please be so kind to explain me where and how to code / copy-paste this into a working function? I’m totally blind about jQuery (my bad)
nevermind me asking
got it figured out
Nice little plugin sir, thanks.
First I stumbled upon the SEO stylesheet, now this? Keep it up, you’re on fire!
@Judd – glad you’ve found them helpful.
Hey, this is great, successfully tested in IE6, Chrome, Opera, Safari, however it surprisingly does not work in Firefox 2 (I’ve got 2.0.0.19). Any ideas how to make it work in FF2?
Hi! Great! Do you know how to center a div in the browser window?
@Jonas – That’s done with CSS. The container div should be
text-align:center, and the centered div should bemargin:0 auto;THANK YOU!!!!!!!!!!!!!!!!!!!!!!!!!! THANK YOU THANK YOU, YOU Just saved me another 3 hours or trying to make a classic Jquery method to work with each function. (I’m kinda clueless to javascript in general, still learning the basics).
Thanks again
@Alexandru – Glad I could help
Anther quick question
If i set it to the container div will it work?
(trying to make a new website and i have to make it vertically aligned to the top and bottom sides) so i am wondering does it work by calculating the window height or I have to make another div (and not set everything to it) and slap my container inside said div.
Thanks
wow ! awesome. Just tried with an image and works very well. I added a bind on resize window to replace the image on resize
$(window).bind(‘resize’, function() {
$(‘#content img’).vAlign();
});
Thanks for your code
Hey Zack:
Thanks for doing this plugin as a social service:)
Unfortunately, I am a technical idiot.. and dont know – where to exactly copy and paste this code of yours
-> as you guessed ..
So -> for the technical idiots like me -> would you kindly spill some ink ? and let me know wher to copy and paste : in other words: copy and paste too -> is an art -> you have to know what to copy, where to copy and how much to copy
and yes.. I dont even know THAT MUCH
thanks
ajay mishra
ceo nomolisa.com
Yes, I know this guy, and he’s not kidding about being a technical idiot!
Nice clean code there, great article again Zack!
I added a way to reposition the stuff when the window is resized.
(I used this for a full screen document with one div that always should be centered).
I’m not a jquery king, so I hope it’s all good;
$(document).ready(function(){
$(“.content”).vAlign();
});
$(window).bind(‘resize’, function(){
$(“.content”).vAlign();
});
BRILLIANT.
The IE demon won’t eat THIS afternoon.
Hi! I seem to be having some trouble with elements that need to be hidden at start. For example if i want to use it as a title that will appear when i hover over an image. It doesnt seem to get “ah” since the element is hidden.
Ah .. i figured out a solution while i was writing this. I used opacity:0 and opacity:1 as hover. The elemnt is there and its height can be read. But its a side road, any better solutions?
Thanks for the excellent post. The vertical align function has already helped me out tremendously!
We had some discussion on Stack Overflow about issues when (probably) some external CSS was not yet loaded. When not yet loaded then the value for “$(this).height()” may yield zero, or some value that does not match the actual height. Placing the code to load your CSS before the code to load jQuery may help, though things seem to be more complex than I would have imagined. Anyway, see http://stackoverflow.com/questions/1324568/is-document-ready-also-css-ready/
If you want the item to be vertically aligned to the window (i.e the parent of the element you want to align vertically is BODY), then change:
$(this).parent().height();
to
$(window).height();
Thats all! (Note that this will make the code only work in this instance though)
Hi Zack,
I have a problem with my website wich is still in developpement, I’m trying to understand all the basis, the problem is that all my subcatergories are not aligned (click on “piscines” to access the differents subcategories, so you will see that the images are aligned but not the titles. Will your tips work?
thanks for you help
Youssef
It should, yep. I believe you’ll want to use the following code:
$("div.ProductImage img").vAlign();nice function mate.
I changed my code from:
$(this).css(‘margin-top’, mh); to
$(this).css(‘padding-top’, mh);
because I was having some problems with a UL list. My html code is:
Blah Blah Blah
and I use $(“.valign”).vAlign(); on the
Nice plugin. Really saved me a lot of trouble.
I found one similar, although probably a copy/an enhancement based from yours:
http://cool-javascripts.com/jquery/vertical-alignment-of-contents-inside-an-element-using-jquery.html
I am having problems with multiple instances and I’m not that great with jquery. The first element positions but the rest don’t unless I refresh the browser.
Is where the .each ( ) function
would come into play? If so where would it be placed in the code?
Oh my god, this code is delicious!!
But… I changed it.
if (mh < 0) { $(this).css('margin-top', mh); };That makes sense. You could also do
if(mh != 0)…This work, but maybe you have the margin collapse issue. If this is the case. Put this line before the margin-top line.
$(this).parent().css(‘padding-top’, ‘1px’);
In this example, you would be vertical aligning something with the id “content”. That would look something like this:
<div id="content"><p>This is content that will be centered.</p>
</div>
The code below should be placed under the <head> tag and above the </head> tag. It will only work if you’re using jQuery and it’s been installed properly.
<script type="text/javascript">// Plugin code goes here
$(document).ready(function(){
$("#content").vAlign();
});
</script>
You may want to use
position:absolute; left:-999em;as the “hidden” state; opacity does not have full browser ::cough:: IE ::cough:: support.Then on the hover, use
position:relative;and whatever other stuff you’re doing in thereHmmm yes it would probably be better with hidden positioning, ill give it a try, thanks!
(regarding IE i used filter:alpha(opacity=0) so its cross-browser but i hate using such “hacks”)