Centering a CSS menu without the width (aka Shrink Wrap)

Centering a CSS menu without the width (aka Shrink Wrap)

On a recent project, I ran into an issue where the main navigation needed to be centered and flexible enough to add and remove menu items through a CMS. For those of you not familiar with CSS, this creates an immediate problem: you can not center a block element without first knowing its width. The normal technique is to use auto left and right margins (margin: 0 auto), that are then calculated based off the element's width. But what happens when you don't know the width of the element? Well this plagued me for a while, and unfortunately I didn't word my google searches well enough to turn up any definite answer. So I reverted to using an arcane Javascript function that would grab the width of each menu item and then apply that width to the containing element. However, this caused lots of strange problems: weird flashes if you were hovering over the menu on page load, strange issues that could only be fixed with CSS overflow and z-index, and more. And you should all know my love/hate relationship with Javascript by now. However, after doing some proper research, I found a simple solution using CSS, also known as Shrink Wrapping. Shrink Wrapping is based off the idea of treating an element like a table. You contain the block you want to center in an element with the display style of table (display: table), and then apply the display style table-cell to the centered element (display: table-cell), and bingo! it works.
#nav-contain{   display:table;   margin:0 auto; } ul#nav{   display:table-cell; }
However, getting this to work in IE is tricky. Internet Explorer doesn't support the display table property, even though it's been around for years, and even IE7 doesn't like it. So in order to get it to work you have to use text-center and treat the centered element like an inline element:
#nav-contain{   display:block;   margin:0;   text-align:center; } ul#nav{   display:inline;   zoom: 1; }
You include the CSS using the IE conditional comment (<!--[if IE]>...<![endif]-->). Based on the example I saw there may be some CSS height hacks required. I didn't use them, but used one height declaration instead; an em height (for accessibility). zoom: 1 is required as it forces the element to have a layout. Note: On the examples I found (see below), it said to treat the centered element like an inline-block; however, this wouldn't work for me, so I reverted to the inline example as seen above. I'm not sure if this is because the element I had contained floats or if inline-block is not the proper usage --- Update: If you have floats contained within the element use display: table-cell instead of float: left/right. This will prevent the floats from collapsing into each other (as noted here). --- Some of you out there may already know this tip, but I had never ran into a situation where I needed to center an element without knowing its width. More information: http://css-discuss.incutio.com/?page=CenteringBlockElement http://archivist.incutio.com/viewlist/css-discuss/42280?highlight=horizontally+centered http://www.brunildo.org/test/shrink_img3.html