How to horizontally centre anything with CSS

There two kinds of display elements we work with most of the time, and they are inline-level elements and block-level elements. By default, elements such as <span> and <a> are examples of inline elements whereas <h1>, <h2>, <p> and <div> are examples of block elements. These elements are not forced to stay inline or block. The browser applies basic styling to elements and it is this that gives the elements their seemingly engrained properties.

Just like the browser styles these elements, we can style them too and over-ride the browsers styling.

It’s important to understand the difference between inline-level elements and block-level elements, because different methods are used to centre these different level elements.

Centring text, single and multiple inline-level element

These are definitely the most straight-forward thing to centre with CSS.

The HTML

<div class="center">
	This is some text that will be centred
</div>
<div class="center">
	This is some text as well as a <span>few</span> <span>inline-level elements</span>.
</div>

The CSS

.center{text-align: center;}

All of the text will be centre aligned. You can have a look at the demo.

Centring a block-level element

This is slightly more confusing than text-align: center.

In order to centre a block-level element, the element must have a fixed width and the left and right margin must be set to auto.

The HTML

<div class="block">Example Block<div>

The CSS

.block{margin: 0 auto; width: 100px;}

This will centre the 100px wide block.

That’s it for the single block-level element. Not too confusing, but definitely more complicated than the text-align: center.

Centring multiple block-level elements

This isn’t much trickier than centring a single block-level element.

We will need to wrap the elements we want to centre in a container block-level element and centre the container/parent. Technically, we still centring a single block-level element.

The HTML

<div class="container">
	<div class="block">
	<div class="block">
	<div class="block">
</div>

The CSS

.container{margin: 0 auto; width: 360px;}
.block{background: #333; float: left; height: 100px; margin: 0 10px; width: 100px;}

As you can see, all 3 .blocks fit perfectly in the container. The outer-width (width, margin and padding) of each block is 120px.
120px * 3 = 360px

That’s awesome, we have successfully centred multiple block-level elements. That’s it… Right?

Nope, there is still more.

How do I centre a dynamic amount of block level elements?

This is a tricky question, at least if you don’t know the solution.

What if a user has CMS control and adds another .block to that container div?
Answer: The block will appear below the first block because the container has a set width of 360px.

We could fix that by adding another 120px to the container’s width, but there will probably still be future problems if the amount of .blocks change.

2 solutions

The one solution is so simple it’s almost funny:
Remove the width of the container and change the display to ‘table’.
For example:

.container{display: table; margin: 0 auto;}

Magic!, all solved. Now we can upload and implement, right?

Almost, but we have a problem… or two: IE6 and IE7. Those two browser don’t support CSS 2.1 properly, and display: table is one of the properties they don’t support.

If you insist on getting it to work within IE6 and 7, here is a jQuery solution.

The jQuery

I was faced with this problem before and I used jQuery to calculate the total width of the container’s children, and set that as the container’s width, therefore, if set to margin: 0 auto, it would always be centred. The only downside to this is each child-element has to have the the same width and margin.

jQuery(document).ready(function($){
	var	totalWidth = $('.container').outerWidth(),
		totalChildren = $('.container').children().size(),
		containerWidth = totalWidth * totalChildren;

	$('.container').width(containerWidth);
});

And that’s it.

Hopefully this article solves some of your problems.

Any questions or comments?

  1. Justin M. says:

    Great tutorial! I’ve been searching everywhere for this and all of the other tricks I tried never seemed to work. I think I got hung up with formatting in interior divs with display:inline-block. Thanks for this greatness.

  2. Yves says:

    Thanks, the “display: table;” trick for dynamic length block level elem, without having to add a wrapper (and while the parent is “text-align:left” for instance, otherwise “display:inline-block” should work with a “text-align:center” parent), is very helpful, and works in recent browsers.
    Just wondering: is it actually a trick due to CSS lacking, or is it the recommended way to proceed in this specific case?

  3. nishant says:

    Can you please upload a demo for this article

    1. Jamy Golden says:

      I’m going to upload a new article in a few days which will cover horizontally centering and it comes with demos too.

  4. Abel says:

    Hi, I don’t know if you didn’t explain well but that jquery function is not working for me! :/

    1. Jamy Golden says:

      I did a bit of an update with the code. If you still run into a problem, then I would guess that the browser isn’t loading up jQuery correctly.

Leave a Reply to Yves Cancel reply