Centering Multiple Line Content with CSS

By , 6 October 2007

Centering Multiple Line Content with CSS

At last... an opportunity to spend some quality time blogging :) . I've had some very positive feedback from my previous blogs which is always nice and motivates you to write more. Well, today I wanted to nail a long standing issue with positioning blocks of text in the center of containing elements.

It all started when a customer rang me and said they wanted the text in their menu items wrapped. They were already centered using #menu { line-height: 70px; text-align: center; }, but this method breaks if you need to wrap lines, because both lines become 70px high. So... what should I do? Tell the customer that wrapping text is just too hard?!

Centering Multiple Line Content with CSS

Firstly, why not use a good old html table to align the content? Well, I tried that, and yes it works, but it didn't give me the desired results. The problem is I want my <a> element to occupy the entire cell region and the inline text to be centered. A table can be used to center the <a> element, but then it won't occupy the whole cell.

The W3C actually has a good example of centering blocks using CSS on their website [1], but naturally it doesn't work in Microsoft Internet Explorer. To be honest though, I don't really blame IE for this - the lack of clear support for vertical alignment in the CSS spec is a major problem! The spec defines how vertical-align applies to table cells and inline elements only. Most of us are looking for the behaviour described for table cells, but it can't be used on block elements such as <div> and <p>.

The standards-based solution, which works in Firefox, is to use display: table and display: table-cell in conjunction with the vertical-align. It means you need at least two elements:

<a href="." style="display: table; width: 300px; height: 300px;">
  <span style="display: table-cell; text-align: center; vertical-align: middle;">
    Hello standards<br/>world
  </span>
</a>

To get things to behave in IE, I used absolute positioning with a javascript expression to center the span vertically:

<a href="." style="display: block; position: relative; width: 300px; height: 300px;">
  <span style="display: block; position: absolute; left: 0px; width: 100%;
      text-align: center; cursor: pointer;
      top: expression(this.parentElement.clientHeight / 2 - this.clientHeight / 2);">
    Hello Microsoft<br/>world
  </span>
</a>

View an example of each of these solutions on one page.

The results can be merged using some css hacks (the star hacks are used to target both IE6 and IE7), and the stylesheet looks something like this:

a {
  display: table;
  text-align: center;
  width: 300px;
  height: 300px;
  *display: block;
  *position: relative;
} 

a span {
  display: table-cell;
  vertical-align: middle;
  *display: block;
  *position: absolute;
  *text-align: center;
  *left: 0px;
  *width: 100%;
  *cursor: pointer;
  *top: expression(this.parentElement.clientHeight / 2 - this.clientHeight / 2);
}

View an example of the cross-browser solution.

This method works for me, but I don't particularly like the mess it leaves behind. Perhaps things will improve with CSS3... but somehow I doubt it.

References

[1] http://www.w3.org/Style/Examples/007/center

About Roger Keays

Centering Multiple Line Content with CSS

Roger Keays is an artist, an engineer, and a student of life. He has no fixed address and has left footprints on 40-something different countries around the world. Roger is addicted to surfing. His other interests are music, psychology, languages, the proper use of semicolons, and finding good food.

Leave a Comment

Please visit https://rogerkeays.com/blog/centering-multiple-line-content-with-css to add your comments.

Comment posted by: Gabriel, 13 years ago

Thanks for this! I like it much better than adding ANOTHER wrapper element as in other solutions. IE sucks, so it requires a bunch of wack CSS. At least browsers of the future will ignore it... built to last

Comment posted by: ramu, 15 years ago

very fuddu coading...!