Solstice Coil

Horizontally centering content with dynamic width in CSS

Oh, hai!
You probably came here because you want to know how to dynamically center stuff with CSS. And that's great, because I'm going to show you just that. But wait!
How about you listen to some of my music too? That way you both get the info you want AND you can show off to your friends about this new and cool band that you know about and they don't. Great code and good alternative-progressive rock: It's a win-win situation, really. Enjoy!

Update!
Long overdue, but this solution now finally uses semantic HTML! Yey!

Just returned from a lecture by Christopher Schmitt at the ISOC convention, which was really interesting. He introduced and covered several aspects of CSS to a tough Israeli audience, a congregation that found itself mostly dumbfounded by this "new" technology. Heh, It's about time someone gave those people a nudge. My only caveat with the lecture that he only showed slides and not how live code behaves in a browser. I believe it would have been much more effective had he showed a simple web page and illustrated changes on the fly with Firebug instead of just looking at the code, but maybe that's just me. Anyhow I promised I'll send him my solution to centering content with dynamic width so here it is!

Centering in CSS always requires some amount of work. It's rather easy when you know the exact dimensions of the element you're trying to center - but what happens if you want to horizontally center something of unknown width? For example - a list of links in a footer or a header? After much testing and fiddling around I've come up with a solution that is both viable and cross browser.

The markup goes a little something like this:

<div class="centeringContainer">
	<div class="centered">
		My Content
	</div>
</div>

and the CSS:

.centered{
 	margin-left: auto;
 	margin-right: auto;
 	display: table;
 } 

So what happens here? We're giving our centered span element a display type of "table" rather than "block" or "inline", and since "table" knows how do be centered with auto margins, so does our div. Problem solved...

...or is it? Seems like IE always has a party to poop on and it doesn't like "display: table". Luckily, we can use "display: inline" to switch the div render type from "block" to "inline". This of course requires the entire content to be centered using "text-align: center", hence the centeringContainer div. On top of that, and because of the IE hasLayout bugs we need to enforce the weird propiteray "zoom: 1". This in essence changes nothing in the rendered element, but it does set its hasLayout value to true. So we create an IE only stylesheet file that has this:

.centered{
 	display: inline;
        zoom: 1;
 }
 
 .centeringContainer{
 	text-align: center;
 } 

Slap on conditional comments for IE browsers only that override the default:

<!--[if IE 6]>
	<link rel="stylesheet" href="ie6.css">
<![endif]-->

<!--[if IE 7]>
	<link rel="stylesheet" href="ie7.css">
<![endif]-->

And there you have it. The reason I have two separate conditional stylesheets is just force of habit, since usually I find myself having to rely on these to fix specific bugs in IE6\IE7.

Click here for a clean live example.

- opher
Syndicate content

All content © 2005-2011 Solstice Coil