Centring using CSS

Methods for centring block and inline elements using Cascading Style Sheets

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

Historically, Internet Explorer has suffered from a number of bugs in this area of CSS. Depending on the version and mode it may fail to centre blocks with auto margins and/or centre blocks when text-align: center; is applied to an ancestor.

The good news is that, so long as you are using a Doctype that triggers Standards mode, you don't usually need to worry about these problems; one will only impact versions of Internet Explorer older than IE6, and the other doesn't occur very often.

That said, it is worth having some discussion of the bugs. First a brief description of the problems, along with the work arounds, and then a summary of where they appear.

Bug descriptions and work arounds

The text-align property impacts block elements bug

This issue causes a block element to be centred if its parent element has the rule: text-align: center;

It is rare that a design will include a block which contains both free text and descendent blocks, so this is rarely a problem.

The work around is to wrap all the free text in blocks of their own, and apply the text-align rule to those elements instead of the parent.

The auto margins do not centre blocks bug

The more serious bug prevents auto margins from centring an element.

Happily, it only appears in very old versions of Internet Explorer and in Quirks mode. Unless you need to cater for IE 5.5 and earlier, or you are trying to work in Quirks mode (which is stronly advised against), this won't be a problem.

If you are constrainted by those limitations, then there are a couple of workarounds, neither of them pretty.

Exploit the other bug

Any time the auto margin bug is in effect, the text-align bug is also.

Wrap the element you wish to centre in a div element. Use text-align on the parent to centre the child, and reset the text-align so you don't centre the original contents of the element.

Don't forget to centre the element with auto margins as normal for other browsers.

<div style="text-align: center;">
  <div style="text-align: left; margin: 1em auto; width: 50%;">
  </div>
</div>
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.

Internet Explorer versions and modes impacted by bugs

There are three things that determine if these bugs will appear:

  • The version of Internet Explorer
  • If the browser is in Quirks mode or Standards mode, determined by the Doctype
  • The compatibility mode, determined by a meta element or HTTP header, which may override the Doctype to force Standards or Quirks mode
Versions Affected
Version Mode text-align bug auto margins bug
4 - 5.5 n/a Yes Yes
6-8 Quirks Yes Yes
6-7 Standards Yes No
8+ Standards No No
8+ IE5 (As IE7 Quirks) Yes Yes
8+ IE7 (As IE7 Standards) Yes No
8+ IE8 No No
Quirks mode

In Internet Explorer below 5.5 and in newer versions of Internet Explorer in Quirks mode:

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

In Internet Explorer 6 and 7 in Standards mode, and in newer versions of Internet Explorer in IE7 Compatibility Mode Standards Mode:

  • Auto margins will work
  • Text-align will (incorrectly) influence the position of block descendents
Browser modes without old IE bugs

In other browsers and in Internet Explorer 8 and newer when in Standards mode and either no Compatibility mode or IE 8 or newer Compatibility mode:

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

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.
  • Always use Standards mode!