css iconAt some point, you may have a situation where you want to center multiple elements (maybe <div> elements, or other block elements) on a single line in a fixed-width area. Centering a single element in a fixed area is easy. Just add margin: auto and a fixed width to the element you want to center, and the margins will force the element to center.

There really should be a similar simple way to center multiple elements evenly spaced. It would be nice if CSS had a property called “box-align” which you could set to “center” then the child elements would be centered evenly within their parent.

Well, you can achieve something similar by taking advantage of CSS’s flexibity with “recasting” elements (for lack of a better term). View a demo of what I’ll be describing in this short tutorial.

The Usual Way

Normally, in such a situation, you would just float the boxes, then add left and right margins to space them out accordingly. But that can get a little messy, because IE6 doesn’t like margins on floats, and you always have to have a different id or class for elements on which you don’t want margins (like the last and/or the first).

You can get around the IE6 problem by adding display: inline in an IE6-only declaration, but your code will still be somewhat messy because of the extra code to get the first and/or last item to behave. Also, the last box could fall to the next line in IE.

There’s another solution to this that might work better in certain circumstances.

Use inline-block and control white space

To achieve the same effect as adding floats and margins, you can simply “recast” your block-level elements as inline blocks, and then manipulate the white space between them. Here is how the CSS might look:

#parent {
	width: 615px;
	border: solid 1px #aaa;
	text-align: center;
	font-size: 20px;
	letter-spacing: 35px;
	white-space: nowrap;
	line-height: 12px;
	overflow: hidden;
}

.child {
	width: 100px;
	height: 100px;
	border: solid 1px #ccc;
	display: inline-block;
	vertical-align: middle;
}

In my example above, I’m assuming there are four child boxes, each with the class child, and each 100 pixels by 100 pixels. The boxes are naturally block-level elements, but the CSS changes them to inline-block, which allows them to flow naturally with text and white space. Of course, since we don’t have any text in the parent container, controlling the text and white space will not be a problem.

The parent element (with the id parent in this example) has four key text properties set, and the children have two:

  • text-align makes all inline child elements centered
  • letter-spacing controls the size of each white space unit between boxes
  • white-space: nowrap keeps the last element from potentially dropping to the next line
  • overflow: hidden prevents the box from stretching in IE6
  • vertical-align: middle (on the children) keeps the boxes on the same vertical plane as each other when content is added
  • display: inline-block (obviously)

Internet Explorer Rears its Ugly Head

What would a CSS solution be without an Internet Explorer issue to work around? While this method works exactly the same in every browser (including IE8), IE6 and IE7 don’t cooperate, because they don’t fully support inline-block. To get those browsers to show virtually the same result, you need to add the following CSS:

.child {
	*display: inline;
	*margin: 0 20px 0 20px;
}

The CSS above must apply only to IE6 and IE7, and it has to appear after the other CSS. In my code (and in the code example above) I’ve accomplished this by using the star hack. The asterisk (or star) at the beginning of each line hides both lines from every browser except IE6 and IE7. The margins added here help us get the same visual result, and the new display property is taking advantage of a bug in those browsers that makes a block element work like its inline when you declare display: inline-block followed by display: inline.

Drawbacks / Final Thoughts

Not many drawbacks to this. You just have to make sure the white space and text settings that you apply are reset on any child elements inside the boxes. So, while this may work when you have straight images or other non-text content, it may be more trouble than its worth if your boxes are fully loaded with diverse content.

But nonetheless a good technique to know when you have to center some block elements with equal spacing, and you don’t want to apply extra classes on the end units. And this technique will be even more important when the older versions of IE disappear from general use. But I’m not holding my breath.

View a demo





About the Author: Alex Roman

I’m a 23-year old independent graphic artist based in Romania, Bucharest. I design beautiful, engaging user experiences and intuitive user interfaces for the web. I really love what I do. Want to hire me? Follow me on Facebook or Twitter.





  • Nestor Sulu:

    That works in IE6, until you place some content inside each DIV, then it gets a mess-up.
    Example:

    A
    B

    C
    D

    Center them as explained here, it will not work… any idea? I haven’t found a solution yet. Thanks.

  • lemonade:

    Awesome post, hey I found this story while searching the web for free downloads. Thanks for sharing I’ll share this on facebook about this too.

  • vlad:

    hi Nestor, first of all ie6 is not used any more, by most of the users. Who is still using IE6? Well office computers that cant be installed with any other browser, people that doesn’t know how to install other browser or upgrade ie6.
    http://www.w3schools.com/browsers/browsers_explorer.asp
    If your web application / website has as target programmers or webdesigners or people that knows a bit about computers you dont need to optimize your app/website for IE6
    Anyway I’m working at a company that does websites/web apps/iphone apps/android apps etc… and we have as clients, big television companies… as fox channels, and they don’t want IE6 optimization any more… This is my opinion.

    I dont have IE 6 any more, but i can give you an ideea maybe it will work… dont place html tags that have display:block; as a default parameter. Place a with some text in it and see what happens.