September 19th, 2007 - by Paul OB

Question: “When is a float not a float?”
Answer: “When it doesn’t float to the left or right.”

Today’s modern web designs are utilizing CSS for page layout. One popular CSS property used for page layout is float. The float property causes an element to float against the left or right margin of its parent element. But an often-sited drawback of using floats is that there is no easy way to center them. Most people settle by using a fixed width wrapper that contains the float (or floats). The width of the wrapper must match the float(s) total width and then the wrapper can simply be centered using auto margins. This will effectively center the floated elements as they are now contained within the wrapper. The drawback of this method is that you will need to know the width of the floated content beforehand.

In this article we will describe how you can center a widthless float or a series of widthless floats with relative ease.

Floated Buttons

A common task for a designer is setting up a horizontal navigation menu. There are a number of ways that horizontal menus can be constructed and all have their advantages and disadvantages depending on the situation in hand. The easiest solution is simply to use a list for the menu and set the list element to display:inline so that the menu lines up horizontally across the page.

If the menu is purely text then you can have the menu centered simply by setting the ul to text-align:center causing the inline list elements to be nicely centered on your page. This is fine for simple menus, but if you want the text styled as buttons with padding, shading and various borders, then inline elements are not ideal for this type of styling and the results can be unstable across browsers.

In cases where the menu items have complicated styles applied to them the best option is float the list element instead. This means that the anchor can also be made display:block (or floated also) and this enables the elements to be styled consistently with padding borders and heights if necessary.

First we will need some code to work with — here is some that I prepared earlier:

  1. html,body{
  2. margin:0;
  3. padding:30px 10px;
  4. text-align:center;
  5. }
  6. #outer{
  7. width:780px;
  8. margin:auto;
  9. text-align:left;
  10. border:1px solid #000;
  11. padding:5px;
  12. }
  13. .navwrap ul{
  14. list-style:none;
  15. margin:0;
  16. padding:0;
  17. }
  18. .navwrap li{
  19. border:1px solid #eff2df;
  20. float:left;
  21. margin:0 10px 0 0;
  22. background:#809900;
  23. }
  24. .navwrap li a{
  25. float:left;
  26. border:1px solid #4c7300;
  27. position:relative;
  28. left:-2px;
  29. top:-2px;
  30. background:#eff2df;
  31. color:#4c7300;
  32. text-decoration:none;
  33. padding:6px 10px;
  34. font-weight:bold;
  35. }
  36. .navwrap li a:hover{
  37. background:#809900;
  38. color:#fff;
  39. }
  40. .clearer{
  41. height:1px;
  42. overflow:hidden;
  43. margin-top:-1px;
  44. clear:both;
  45. }
  1. <div id="outer">
  2.  <div class="navwrap">
  3.   <ul>
  4.    <li><a href="#">Button 1</a></li>
  5.    <li><a href="#">Button 2's a bit longer</a></li>
  6.    <li><a href="#">This is Button 3</a></li>
  7.   </ul>
  8.  </div>
  9.  <div class="clearer"></div>
  10. </div>

(Note: The extra div used for .navwrap isn’t necessary for this example, but I have included it to make the examples which follow easier to understand. The above example could have been done without using the extra div by applying the styling directly to the ul instead.)

The drawback of floating the list element is that the menu now aligns to the left of the page (or right depending on the value used), as can be seen in Figure 1 which is produced by running the above code:

Figure 1
wfig1.jpg

Now in order to center the floated menu you would typically wrap the menu in another static div and apply a fixed width as well as set margins to auto. But this presents a small problem in that in the above example the menu items have no widths defined and therefore the total width of our menu is unknown. We could of course set widths for each menu item but it would then be necessary to add classes to each individual menu item, which is a bit of a pain to do and will also restrict the menu to always being that same size. If we wanted different (or dynamic) menu items on various pages then we would have to keep changing the classes for every instance which would quickly become unmanageable or even impossible for dynamic data.

Therefore it would be best if there was a way to center the menu that didn’t involve setting any specific widths anywhere!

It’s All Relative

Once again we find ourselves calling on our old friend — Relative Positioning.

The premise is simple — it 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. Recall that relative positioning maintains the flow of the document and allows other content to flow underneath quite normally.

The basic section of (stripped down) code is as follows:

  1. .navwrap{
  2. float:left;
  3. position:relative;
  4. left:50%;
  5. }
  6. .navwrap ul{
  7. position:relative;
  8. left:-50%;
  9. }

Unfortunately IE needs a helping hand and requires the inner element to be floated as well. This can be achieved by including an IE-only style using conditional comments.

  1. <!--[if IE ]>-->
  2. .navwrap ul{float:left;}
  3. <![endif]-->

If you look at Figure 2 you will see the effect that this has had on our layout.

Figure 2
wfig2.jpg

The menu is now centered nicely, but what I haven’t shown is that the browser now shows a horizontal scrollbar (in some browsers). The reason for this is that the relative positioning moved the element outside the confines of the window and although we subsequently dragged it back into view the browser still thinks it is off-screen somewhere.

To combat this effect we can simply add overflow:hidden on a parent div which will kill the horizontal scrollbar. You can use any parent, but you may be better advised to specifically add an extra element to do this rather than utilising the page wrapper (as in my example) as you may not want to hide the overflow on that.

The full CSS and HTML can be found in this live example.

Here is a screenshot of the above link showing various sized menus:

Figure 3
wfig3.jpg

Drawbacks

The drawbacks to this method are mainly the extra non-semantic div wrapper that is needed to accomplish this effect and also the overflow:hidden that is needed on a parent element. Otherwise the method works well across modern browsers although, as I always say, make sure you check in the browsers you want to support before using any advanced methods like this.

Other solutions

There is in fact another way of centering elements like this and that involves using display:table for Opera and Mozilla browsers and using display:inline-block for IE. This new method has one small advantage over the floated method in that in a fluid width environment the menu can wrap and the wrapping item also becomes centered. This is unlike the float version above where a wrapping element would align to the left of the centered menu.

However, you will have to wait until part 2 of the article to see how this can be done, but meanwhile you can have fun with your floats.

Be Sociable, Share!

34 Responses to “When Is a Float Not a Float?”

1 bigguy

In your live example “then applying a 500%:”
looks like an extra “0″!

2 Paul OB

Well Spotted – Fixed now :)

3 Bram.us » CSS Centered Horizontal List, With Floats

[...] trick: When is a float not a float? Spread the [...]

4 m rushworth

This is simple. use floats when you attribute a width to the element, otherwise use display:inline

5 Paul OB

@M Rushworth: Did you not read the article as your comments make no sense. The article was about widthless floats and both your points were covered in the article :).

Assigning a width to the float won’t allow you to centre it anyway. You still have to put it in a wrapper of the correct width and use auto margins as stated in the article.

However that defeats the purpose where you have different sized menus on different pages or indeed use dynamic data for elements where you don’t know the width.

Using display inline is not an option either for complicated sections where borders, margin and padding are used on multiple elements, as inline elements are inconsistent in the way that padding, borders and margins are handled in a cross browser way. There are also limitations as to what you can achieve when styling inline like this due to the way the inline box model is constructed.

The safest and most consistent way to style elements like this is to keep them as block level display elements which can be achieved by floating as in my example.

6 David Hopkins

Thanks for sharing this find. My solution for this problem is slightly more bulky.

Another issuse with the auto margin center trick is that it can cause some weird offsetting if its ancestors nodes have positioning. Only in IE 6&7 of course :P

7 Golgotha

@David Hopkins: nice website, you really went to town with the JavaScript!

8 Klaus Paiva

Nice one, thanks!

I already used this one: http://www.cssplay.co.uk/menus/centered.html – it uses the display: table method you said above.

9 links for 2007-09-24 : Christopher Schmitt

[...] When Is a Float Not a Float? “When it doesn’t float to the left or right.” (tags: css float webdesign tutorial design webdev tips) [...]

10 napyfab:blog» Blog Archive » links for 2007-09-24

[...] When Is a Float Not a Float? (tags: css float tutorial webdev webdesign design) [...]

11 links for 2007-09-25 « Simply… A User

[...] When Is a Float Not a Float? (tags: webdesign tutorial float css design webdev tips technique howto **) [...]

12 David Hopkins

Thanks. I think i’ve learned that JavaScript is only a good idea when you have lots of financial backing :)

13 sniurkst

You have saved my day. Thank you for great and helpful article!

14 Chris

Interesting! I’ve seen the display:inline display:table method used before, but the otherway around – using display:table for IE. Will be interested to see how this CSS fix works.

15 Paul OB

Hi Chris, Thanks for your comments :)

I’m not sure if you meant to say “using display:table for IE” or whether it was a typo but I should point out that IE (including IE7) does not support display:table.

http://reference.sitepoint.com/css/display

I believe IE8 will be supporting display:table though but it will be a long wait :)

Thanks for sharing this. I have tested and it works.

17 SEO Manchester Web Design

Great resource and to the point, there are so man articles out there that do not consider browser compatibility with CSS isues like this, but it looks to me like you have this one covered…

18 Fay Webber

thanks for this Article; worked Beautifully

19 Matthew 'Web Design' Adams

great tips.

Thank you

20 Getoninter.net Web Development

Very useful tips thanks guys.

21 Bruce

Thank you very much. Worked perfectly!

22 João Ishiwatari

Hi guys, this article fix a lot of my problems, but when Im using navwrap li{list-style-image} the FF, Safari works well, IE sux don´t display their images …

PS: Sorry, but i don´t know english very well.

23 Slicing skill list - Wolf’s Little Store

[...] Centering without knowing the width of an element: centered widthless floats [...]

24 Emanuel

This is the most simple and clear solution I found. Thanks.
In the example you gave, between the different menus (ul) you add the .clearer class (IE needs that).

If I want to add nested ul within the any li, what should I do to make it working in IE (right now there is a mess once I add a nested ul)?

25 Paul OB

Hi,

If you are going to have nested uls then you need to take care of the cascade and cancel out any styles that you don’t want on the nested elements.

e.g. if you have this on the parent:
.navwrap ul{
position:relative;
left:-50%;
}

Then for the child you would need to say:

.navwrap ul ul{
left:0;
}

The same would be true for any of the list styles.

.navwrap li{styles…..}
.navwrap lo li{cancel out styles}

etc.

Without seeing your code I can’t really see where you are going wrong :)

26 Paul OB

excuse the typo in the above :)

27 Emanuel

Thanks. That was helpful and I made it with 4 levels (the link is in the website URL field of this form).
Now, my next challenge is turn it from right to left. Though I almost did it for FF, with IE (I test it on 6 and 8) I get strange results. Even with one level only. When I float the li to the right (in order to present the buttons from right to left), the main ul takes place across the entire width of of the container div. From there it is a mess :-(
(I’ll be glad if you’ll look at the code, in the same file).

28 Paul OB

Hi Emanuel,

Unfortunately IE has a major bug when you float right inside a floated container and the float effectively becomes 100% wide and therefore it can’t really be centred.

You need to always float left inside left floated containers unless they both have defined widths. There is no cure for this bug but to avoid it.

I’m not sure why you would want to reverse the order anyway as the original is in a logical order anyway :).

29 Emanuel

Thanks for the info.

Right to left menu – well, there are other languages, from right to left. Hebrew in my case. I know, ‘Right to Left’ and ‘logical’ don’t go together :-) but that what we have to live with…

30 Paul OB

Ah – Ok, I understand now :)

You will just have to reverse the html order instead.

It’s a nasty bug and not just confined to this layout but to any floated elements where you float right in a floated parent where no width is defined.

31 seo leeds

I think it was well explained….some people only read what they want to see!

32 Kitchens Norwich

Really informative post, found the solution I have been searching for. Much thanks!!!

33 Tiago Araujo

Thank you!!

34 MiB

Now, why would I want to center the navigation? That’s just plain ugly.

That said, centering without absolute widths is very useful..

Share your thoughts...

mulberry sale spyder womens jacket cheap new balance 574 mulberry outlet cheap new balance 574 arcteryx outlet mulberry sale spyder womens jacket mulberry sale spyder womens jacket mulberry outlet mulberry outlet new balance 574

Popular Articles

Top 10 Commentators


Subscribe to this feed! Subscribe by Email!

Random Bits Podcast

You need to download the Flash player from Adobe

Blogs Worth Reading