CSS tips: properly align HTML elements vertically and horizontally using CSS

Click to see live example

Without doubt one of the most basic and important steps of designing any kind of layout is the ability to position and align elements. It’s also one of the things that cause people beginning to use CSS stumble and helplessly scratch their heads. There many wrong ways to do it, and even more ways that seemingly should work, but don’t. In this post I will explain the most useful ways to align any html element (be it a div, an image or whatever you could want) both horizontally and vertically. If you were ever frustrated by the fact that “vertical-align:middle” and “text-align:center” don’t seem to work in certain (read: almost all) situations – this post is for you.

So what makes a method good

I consider a way to achieve something with HTML and CSS good, when it meets the following requirements;

  • works the same way across all modern browsers,
  • doesn’t introduce unnecessary markup,
  • uses html tags and attributes with accordance to their purpose,
  • works for a whole class of elements instead of targeting specific ones,
  • is logical and understandable code-wise.

Let me make this clear, that I consider inline styling, element-specific margin and padding positioning, using floats for positioning bad and wrong even though most of the time it’s possible to achieve the desired effect using those techniques.

To demonstrate the good and useful ways I’ve prepared for you a live example of how to align and position elements using CSS. All the following explanations will be in reference to the examples on that page, so it’s a good idea to keep it open in another tab or window. The example demonstrates how children can be aligned within their parent element, and what exactly happens to its margin and padding. To highlight it I used colours similar to those used by your Firebug (or similar) plugin. If you don’t yet use it I can’t stress enough how important it is for you to install it and familiarize yourself with it.

Overview of good ways to position and align HTML elements

  • Example 1; using “text-align” for the parent container and “vertical-align” for its child elements
  • Examples 2 and 3; considerate use of the “float” property,
  • Examples 3 and 4; absolute positioning.

Let’s now analyse how each of those techniques works. In the examples, our goal was to align all three of the boxes vertically to the middle of their container, and horizontally to the right.

Using text-align and vertical-align

This is by far the best method. If you look at the example, you will see that all our three boxes are nicely aligned the way we wanted them to. Their height dictates the height of their parent container, to align them vertically we used the rule:

DIV.box  {  vertical-align:middle; }

To align them to the right we used for their parent container:

SECTION.text-aligned  {  text-align:right; }

The above two rules only make sense when we are working with elements of the inline or inline-block type. As you should know, it’s the nature of block type elements (such as DIV’s) to assume 100% width automatically, and place themselves in a new line. It is impossible to align block elements in this way, and so to use this method you need to make your child elements inline-blocks. It’s very easy and cross-browser compatible, as explained in this post, and the snippet below:

DIV.box  {  display:inline-block; *display:inline; zoom:1; }

With this method, the margin and padding of the parent element is preserved and everything works as advertised.

Using the float property to align elements

The float property’s purpose is to make text flow around images, drawings and similar elements. It can of course be used to align and position other elements, but only when used correctly. All you need to do to use it is to apply the following rule to an element you wish to align:

SECTION.floated DIV.box  {  float:right; }

But take a while to carefully observe the effects of doing so:

  • The parent element no longer seems to contain the children. It collapses to zero height, so that only the padding seems to remain,
  • you loose the possibility to control the bottom spacing of your elements using padding,
  • the order of the elements is inverted,
  • it is impossible to align them vertically with “vertical-align” anymore – you’re stuck with element-specific margin or padding,
  • all inline content below the parent container will move upwards, flowing over your floated elements, as explained here.

This is pretty severe, isn’t it? Granted – most of the time you don’t give a rat’s ass about how the parent container looks. It probably is invisible, having no background or border. The above mentioned collapsing of the parent can be remedied by using the overflow property, as it is used in the next example. But is it really worth it? It’s not, and floats should not be used for positioning unless there’s no other way.

Using absolute positioning

Now the examples for this technique may look a bit dramatic and not how we intended them to look, but actually this method is very useful. It was created exactly for the purpose of positioning elements all over the desired area. Each absolutely positioned element can be thought about as another “layer” – just like in some graphics design program. Notice how in the example, our boxes locate themselves above the footer link to my website, as if they were on another layer above it (which they are).

To give your element absolute position, you need to make one of it’s parents your “region of interest”. If you don’t, the whole page (the BODY element, that is parent to all the layout elements) will be this region and you will be able to position your element all over the screen:

SECTION.absolutely-positioned>DIV  {  position:relative; }

Now you can move the element freely within this region by specifying top, right, bottom and left values in pixels, percent or whatever legal units you like.

SECTION.absolutely-positioned>DIV>DIV  {  position:absolute; right:0px; top:0px; }

This is not in the example, but the sister-property of “position:absolute”, that is “position:relative” lets you change position of your element relative to its default position. It is very useful to fine-tune your layout at some late stage of development.

DIV  {  position:relative; right:50px; top:20px; }

You can have any number of layers (absolutely positioned child elements within one parent) you wish, but please look at the last example to understand what happens to the parent itself. Similarily to its reaction when having all its childeren floated, the parent collapses as if it was empty. There is nothing we can do to prevent that (except put inside some regular content, of given height). Applying the overflow property in this case only crops the absolutely positioned DIV containing our colored boxes. We absolutely positioned only the DIV containing our three colored boxes to preserve the vertical alignment within it. If we absolutely positioned the boxes themselves, they would land stacked, on top of each other. Notice that the DIV we positioned this way lost its default block behavior, and is no longer of 100% width, rather both its width and height are dictated by the dimensions of the children.

And that’s it!

I’m sure there are other aspects and conclusions that can be drawn from those and similar examples, but this should already start you going. Feedback? Errors? Omissions? Feel free to comment below.

  • Sara

    Hi, good notes… keep it coming!
    By the way I have tested your contribution for osCommerce admin buttons. It doesn’t work if the original functions contains parameters. Is there a fix?

  • TheFutureBlues

    Hey Sara, thanks for the feedback!
    I also noticed sometimes back that that contribution doesn’t work 100% of the time. I resorted to using the default button function in those cases (when its parameters argument is not empty). I will make sure to look into it the next time I work on my clients’ store.