Centre widthless floats.... like these:

It is normally stated that you cannot centre floated elements but this is not quite true. It's true that usually you can only float left or float right but if you have a group of buttons for a menu and you want them to be fluid in width then it would be nice to have them all float in the centre of the page. There is no problem if the floats have a width because you can then ascertain the main parents width and use margin:auto to center the whole block. However that means that the floats cannot be a fluid width (i.e. shrinkwrap their content) or you would have to class each individual element and apply a different width to each which is a little unsatisfactory.

So how can this be achieved more simply then?

The premise is simple and basically just involves a widthless float that is placed 50% from the left using position:relative. The nested inner element is then reversed and a negative relative position of 50% (-50%) is applied. This has the effect of placing the element in the center. Relative positioning maintains the flow and allows other content to flow underneath.

Code:

#buttons{
float:left;
position:relative;
left:50%;
text-align:left;
}
#buttons ul{
list-style:none;
position:relative;
left:-50%;
}

#buttons li{float:left;position:relative;}/* ie needs position:relative here*/

#buttons a{
text-decoration:none;
margin:10px;
background:red;
float:left;
border:2px outset blue;
color:#fff;
padding:2px 5px;
text-align:center;
white-space:nowrap;

}
#buttons a:hover{ border:2px inset blue;color:red;background:#f2f2f2;}
#content{overflow:hidden}/* hide horizontal scrollbar*/

The above demo should work in most modern browsers and will work in ie5 - 7. (It doesn't work in ie5 mac but you can achieve a similar effect using display:inline-block instead of floats so view source for the full details .)

Here is another example using the same technique

Drawbacks

The drawbacks are mainly that when the floats wrap at shorter screen-widths then the element that has wrapped will not align to the center. That doesn't seem to be much of a problem to me but you may think differently. In a fixed width scenario there will of course be no need to wrap and will work fine.

There is also a horizontal scrollbar problem where the width of the centred floats are more than half the width of the the container that they are centered in and a horizontal scrollbar will apear on the window at smaller screensizes. This can be cured by applying overflow:hidden to a parent containner and should really not be much bother.

The same techniques could most likely be applied to absolute elements as their behaviour of shrink-wrapping contents is the same as floats. However absolute elements would be removed from the flow so its not so useful

Another Option

We can achieve a similar effect by not using floats but using display:table for Mozilla/Opera and using display:inline-block for all IE. IE only understands display:inline-block on inline elements but fortunately if you first make the block level element display:inline-block and then declare it as display:inline in the next style block it now treats the block level element as display:inine-block. This is also consistent in ie7 and IE8 has proper support for inline-block anyway.

Note: The actual mechanism for this to work is that any inline element that is in "haslayout" mode will be treated as inline-block. See my inline-block article for the full rundown on why and how this works.

Also note that there is a long standing gecko bug when using display:table and in most cases you would need to include and intermediary element set to display:table-row or on first load the page may be broken.

<style type="text/css">

.navcentre {
margin:10px auto;
display:table;
border:1px solid #000;
padding:2px;
white-space:nowrap;
}
.navcentre ul {
list-style:none;
margin:0;
padding:0;
display:table-row;
white-space:nowrap;
}

.navcentre ul li{
display:table-cell;
}
.navcentre ul a{
display:block;
padding:4px 10px;
text-decoration:none;
background:#ffffcc;
border:1px solid #ff0000;
}
.navcentre ul a:hover{background:red;color:#fff}

</style>
<!--[if lt IE 8]>
<style type="text/css">
.navcentre ul {display:inline-block;}
.navcentre ul{display:inline; }
.navcentre ul li{display:inline-block}
.navcentre ul li{ display:inline;}
.navcentre ul a{ display:inline-block;}
.navcentre{text-align:center}
</style>
<![endif]-->

As usual use at your own risk and test thoroughly on the platforms you want to support. Any problems or improvements then email me at paul@pmob.co.uk although I can't guarantee to answer all emails.