Vertical alignment of contents inside an element using jQuery

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 andthe 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-topproperty.

Code

(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.

Hope it was useful