Dorward's Ramblings

Centring using CSS

Published on

Introduction

Back in the days of HTML 3.x and the transitional variants of HTML 4.x and XHTML 1.0 a number of elements supported the align attribute. How it acted depended on what element it was applied to and there is no direct translation for CSS. How you centre elements depends on the type of element.

Please note that for conciseness the examples in this document make use of inline style. In practice inline style is not encouraged and you should use external style sheets.

Inline Content

Inline content includes such things as text, images, <strong> and <span>. To centre inline content use the CSS text-align property applied to a block level container with the content to be aligned inside.

<h1 style="text-align: center;">
  My Heading
</h1>

Yes, it is badly named. "inline-align" would probably have been a better choice.

Point of clarification: While the text-align property is applied to the <h1>, the content it positions is the text inside the element, not the element itself.

Block Level Content

Block level content includes such elements as <h1>, <h2>, <p>, <table>, and <div>. To centre block level elements set their left and right margins to auto (but see IE Bugs).

<h1 style="margin-left: auto; margin-right: auto;">
  My Heading
</h1>

However, the default width for most block level elements is auto, which fills the available area on screen. Just being centred places it in the same position as left alignment. If you wish it to be visually centred you should set a width (or a max-width although Internet Explorer 6 and earlier do not support this, and IE 7 only supports it in standards mode).

<h1 style="margin-left: auto; margin-right: auto; width: 50%;">
  My Heading
</h1>

Inline Content and the Block Holding It

A common mistake people make after reading this article is to think "I want to centre the text inside my <h1>, it is a block, therefore I must alter the margins.". For clarification then, I will repeat: text is inline content.

[Fig] Centred elements and text

In the above image there are three block level elements. To make it clear what is happening their width is constrained (remember: this is not the default except for tables) and a border is added.

The top element (X) has its inline content centred. By default most block level elements, <table> being the obvious exception, are as wide as the space available to hold them, so this would usually centre the content on screen.

<h1 style="text-align: center">
 X
</h1>

The bottom element (Z) is centred itself using the block technique. Note that the text inside is still left aligned. If the width was not constrained, this centring would have no visible effect on the element.

<h1 style="margin-left: auto; margin-right: auto;">
 Z
</h1>

The middle element (Y) has both its inline content centred and is centred itself with the block technique.

<h1 style="margin-left: auto; margin-right: auto; text-align: center;">
 Y
</h1>

Internet Explorer Bugs and Block Level Content

Unfortunately the most commonly used browser on the market - Microsoft Internet Explorer for Windows - has a fairly serious bug regarding the treatment of block level elements and margins. Depending on the version and mode it may treat such elements as inline content regarding centring. The mode IE uses is based upon the DOCTYPE provided at the top of the HTML document, this is called Doctype Switching.

Versions Affected
Version Mode Bug appears
4 - 5.5n/aYes
6-7QuirksYes
6-7StandardsNo

When the bug is triggered:

  • Auto margins will not work
  • Text-align will (incorrectly) influence the position of block descendents

When the bug is not triggered, in Internet Explorer:

  • Auto margins will work
  • Text-align will (incorrectly) influence the position of block descendents

In other browsers:

  • Auto margins will work
  • Text-align will not influence the position of block descendents

It is possible to work around this, but both methods are something of a nasty hack.

The inline CSS hack

As the browser treats block level elements as inline content (as far as centring goes), they are affected by the text-align property, so the element can be placed in a container and centred using text-align. The element then needs to have its own text-align reset to left.

<div style="text-align: center;">
  <div style="text-align: left; margin: 1em auto; width: 50%;">
  </div>
</div>

NB: margin: 1em auto; sets the top and bottom margins to 1em and the left and right margins to auto. It is used here because the expanded example was causing horizontal scrolling in a high proportion of systems.

The JavaScript hack

A method that keeps the markup somewhat cleaner, but at the cost of failure if JavaScript is disabled is David Schontzler's Internet Explorer Margin Fix script.

Summary

  • margin-left: auto; margin-right: auto; centres a block level element.
  • text-align: center; centres the inline content of a block level element.
  • MSIE has bugs that result in it treating block level content as inline content (for centring) under some circumstances.