I think, therefore I blog

Fluid CSS Menus and Sub-Pixel Workaround

By , 28 January 2009

Fluid CSS Menus and Sub-Pixel Workaround

A long standing CSS problem, best described by John Resig in his blog, is the different approach browsers use when rounding widths calculated from percentages. Firefox rounds alternately up and down in order to make elements fit perfectly, Opera and Safari always round down so that elements will never overflow the container, and Internet Explorer always rounds up so elements often overflow their container and developers get to practise using profanities.

My use case is a fluid css menu with no gaps between the elements or at the end. If you don't know how to build css menus you might want to start by reading my blog on css menus. CSS menus are useful because they are built with <ul> and <li> markup which is a natural representation for hierarchies. The problem is that since menu items are floated, using percentage widths does not guarantee the space will used perfectly (unlike tables).

The basic concept behind the workaround is to leave the last element of the list unfloated so it occupies the entire width of the menu bar underneath the floated elements. Essentially the last item has the following style:

.web_cssMenu li.web_last { float: none; width: auto; }
Fluid CSS Menus and Sub-Pixel Workaround

There are, as you might expect, a few issues with this idea:

  • Standards-compliant browsers stack the last item above the floated ones.
  • IE6 and IE7 have to be put in hasLayout() mode to rendered the last item as a block.
  • IE6 makes a gap between the last two items because of its three pixel gap defect.
  • As the width of the last item is essentially 100%, you have to be more careful about background styles.

Most of these problems can all be resolved with a little additional styling. The 3px gap can be fixed by adding a negative margin to the second last element, but this fix makes more code pollution and is not really worth applying. The complete set of changes are then:

.web_cssMenu li { z-index: 2; background: inherit; }
.web_cssMenu li.web_last { float: none; width: auto; z-index: 1; }

Of course you need the rest of the css menus styles to get a complete picture of what I'm talking about:

View a complete example of my Fluid CSS Menus and Sub-Pixel Workaround.

There are other problems with floated elements (e.g. heights), but hopefully this is trick will solve a problem for you until something better comes along.


About Roger Keays

Fluid CSS Menus and Sub-Pixel Workaround

Roger Keays is an artist, an engineer, and a student of life. Since he left Australia in 2009, he has been living as a digital nomad in over 40 different countries around the world. Roger is addicted to surfing. His other interests are music, psychology, languages, and finding good food. Click here to subscribe to his weekly blog, or stalk him on Facebook and Twitter.

Leave a Comment

Please visit https://RogerKeays.com/blog/fluid-css-menus-and-sub-pixel-workaround to add your comments.

Comment posted by: , 7 years ago

IE6? Woah... could be anything. My approach to tackling IE defects is generally to try adding zoom: 1; or position: relative; at random to various elements until it works. Swearing also seems to help sometimes.

Comment posted by: Vasyl Mosiychuk, 7 years ago

In IE6, when I bring the cursor to the menu item (link hover) then the entire menu unit moves in the left on 1-2 px. How can I fix this?

Join Over 1000 Subscribers

I write every Sunday about travel, psychology, and technology. Thousands of people just like you have already subscribed—and for good reason. It'll change your life. And it's free :)

Read a Good Book

“A spellbinding true story of love, passion and adventure. One can’t help but be swept away by 100% Love Guaranteed.” —Dr Tammie Matson, author of Elephant Dance.

Chat For A While

Your Vote Matters

Which animal will take over when humans go extinct?