Vertical alignment of contents inside an element using jQuery

January 8, 2009 by admin · 10 Comments
Filed under: jQuery, Tutorials 

One of the old problems! Vertical alignment of contents inside an element. For those who don’t know about this issue,

What is the issue?

  • For eg; there is an area (e.g. <div> or <p>) with known height in the page (For eg: 300px;)
  • an internal object (typically a paragraph, image etc) is inside the area and the height is unknown(May be this content is from a table – we don’t know how much is the text)
  • This object should be centered vertically inside the required area.
  • Tables should not be used.

Though there is a CSS property vertical-align, it won’t work like attribute valign in HTML tables. CSS property vertical-align doesn’t seem to be able to solve this vertical alignment problem.

There were ofcourse a couple of solutions using css. But all involves elements inside an element (For eg: <div>inside another <div> and style). But this may be difficult for bloggers, who want to show some content in special formatting (For eg: In my site, notes are shown in a special style). For eg: you want to give a 200px height to a <p> element and vertically center the elements (Same was the case with mine).

So the simplest method is to use javascript. Here I am describing how to solve the vertical alignment issue with jQuery.

The logic:

  1. Find the content inside the element
  2. Create another element inside it and assign the content to the newly created element
  3. Find the height of the new element
  4. Adjust the height of the parent if required (the new height may be more than the given one)
  5. Find the margin, and assign it to the new element using css margin-top property.

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(function ($) {
    $.fn.vAlign = function(container) {
        return this.each(function(i){
	   if(container == null) {
	      container = 'div';
	   }
	   var paddingPx = 10; //change this value as you need (It is the extra height for the parent element)
	   $(this).html("<" + container + ">" + $(this).html() + "</" + container + ">");
	   var el = $(this).children(container + ":first");
	   var elh = $(el).height(); //new element height
	   var ph = $(this).height(); //parent height
	   if(elh > ph) { //if new element height is larger apply this to parent
	       $(this).height(elh + paddingPx);
	       ph = elh + paddingPx;
	   }
	   var nh = (ph - elh) / 2; //new margin to apply
	   $(el).css('margin-top', nh);
        });
     };
})(jQuery);

A little explanation of function

  • First three lines are for the normal jQuery chainable methods
  • If no container is given, <div> is used
  • Line # 7 is for the padding height. It will make sure that there is enough padding even if the height of the new element is larger than the parent. For eg: If you want to ensure that 5px width should be there for top and bottom give the value 10
  • Line # 8 creates the new container with the existing content
  • Line #9 – 11 finds the height of the new element, and newly created element
  • Line #12 – 15 ensures that the parent div has enough height and padding to hold the new element
  • Next lines calculates the center value and applies it to the newly created element using the css margin-top property

Usage

Include the jQuery library and then include this function in your script file or html.

Do not copy from the above code, it is formatted for display and will not work as javascript. Please download the files (Scroll below)

Just call the function vAlign() with the required element. The contents inside will be automatically aligned vertically. You may optionally speciy the new element to be created. Useful, if you want to create a <p> element inside instead of a <div>. By default <div> elements will be created.

Eg:

$("p.special").vAlign();
$("div.info").vAlign("p"); //This will create &lt;p&gt; as the holder element.
$("p.warn").vAlign("span"); //This will create a &lt;span&gt; element.
$("p.warn").vAlign().css("color","red"); //Yes, you can chanin methods.

<span>selements are inline elements, the block properties do not apply to them. So if you want to use inline elements like <span>, <a> then the display:block property should be applied.

For eg:

p.warn span {
   display: block;
}

Advantages:

  1. No need to worry about additional mark ups and style. All required styles and markups will be generated automatically
  2. Content can grow
  3. Simple for content entry

Disadvantages:

  • The only disadvantage is it is javascript based and if javascript is turned off it will not work. But this is a very rare case in the modern world. Even the hand held devices support javascript and there is no reason to turn it off.

Demo

This one is a demo of vertical aligning with jQuery. Or you can view a demo here

Download

Download the demo

Hope it was useful :)

Related posts:

  1. Building a reusabe font size controller interface using jQuery
  2. Add icons to your links automatically using jQuery & CSS
  3. jQuery seekAttention plugin to get the users attention

If you like this post, please share it so that others can also find this

Comments

10 Responses to “Vertical alignment of contents inside an element using jQuery”
  1. Kyle Simpson says:

    I’m wondering if this same approach could be taken to create a html/css construct for the “valign” that would actually “reflow” (that is, keep the content centered vertically if the container changes size (like a browser resize, more content added, etc)?

    There are sites out there which have created some crazy constructs for that, and using a plugin approach like this to artificially create that set of constructs might be really helpful, not just in one-time layouts (like the current plugin) but in fluid layouts which are subject to resize/reflows.

    Here’s an example of persistent vertical centering using CSS/html constructs:

    http://www.jakpsatweb.cz/css/css-vertical-center-solution.html

  2. Chad Kieffer says:

    Thanks for sharing this. I’d just implemented a similar solution. One suggestion, I’d recommend passing the paddingPx as an argument rather than instructing users to change it in the function. Treat it just like you handle the wrapping element, but default to 0, instead of 10.

  3. Emre GULCAN says:

    thank you for your sharing.
    I need a solution like that. I’m using a Css hoverbox image gallery and need align vertically images in a div :)
    I’m trying different solutions for 2 days and now, everything is ok..
    thank you again.
    Regards from Turkey ;)

  4. exeQutor says:

    Nice plugin. Although this looks like a copy/an enhancement based from: http://www.seodenver.com/simple-vertical-align-plugin-for-jquery/

  5. Matt says:

    I am having problems with multiple instances of elements calling the plugin.

    The first element that uses the plugin will vertically center, but often the elements that follow will not unless I refresh the browser.

    I am vertically centering an image in a fixed width div multiple times on a page for a thumbnail gallery. The images vary in height, which is why I can’t use strait css.

    Any ideas on how to solve this issue?

  6. admin says:

    Hi Matt,

    Thanks for visiting my blog and posting comment.
    Regarding your question, I think it may be due to the image tag. If you’re calling this method in document.ready(), this may happen. Because, document.ready() triggers when the html is loaded – at that time, the images may not be downloaded fully and hence the function will fail. It will work the second time as the image is already cached in browser.

    You may try the following to fix the problem.

    If possible, include the width and height attribute to the image tag (May be if you’re using, server side scripts like PHP, it should be possible). Eg: <img width=”300″ height=”200″ src= “” />

    Try calling the align function on window.load() instead of document.ready(). (Because window.load() will be triggered only after loading all images and full dependencies)
    Eg: $(window).load(function(){$(“div.special”).vAlign()});

    Hope this helps :)

  7. Gonz says:

    Thanks for this plugin – this really helped – darn the CSS gods for making this a hassle.

  8. Ricardo Zea says:

    A solution without the need for JavaScript:

    CSS:
    div { display:table-cell; vertical-align:middle; height:300px; }

    HTML:

    Content to be centered

    Works in every browser except IE6 and IE7… although by this point you should be phasing out support for those browsers, at least.

    This script is my backup to the above solution.

    Thanks.

  9. Ricardo Zea says:

    HTML:

    Content to be centered

  10. Ricardo Zea says:

    Not sure how to make code show up…

Speak Your Mind

Tell us what you're thinking...
and oh, if you want a pic to show with your comment, go get a gravatar!