Auto Width Horizontal Menu Bar

This page shows you how to modify the default styles for a Horizontal Menu Bar, so that the menu items within the Menu Bar and its sub-menus are just wide enough to accomodate the longest menu item string. This sounds easy, but you have to employ a couple of workarounds for specific IE and Mozilla/FireFox layout bugs. These layout bugs do not occur if you specify widths on menu items as is done in the default Menu Bar stylesheet.

Below, you'll notice that each CSS code sample starts off by including the default menu bar style sheet, and then declares a <style> block immediately after it, to override some of the default style properties set in the style sheet. The code is presented this way to show the minimal set of changes that are necessary to accomplish the task. If you want these changes to affect more than one page, then you may want to integrate these changes directly into the style sheet.

This is what the standard Horizontal Menu Bar looks like:

 

But when you start using long strings in both the menu bar and sub menus, it can look like this:

 

The default CSS for menu items in both the menu bar and its sub menus have a width property specified on them that give them a default with of 8.2em, which gives all of the menus a uniform look when the text fits neatly within that width, but it forces any text that is wider than that to wrap or hang out of the menu.

Removing the specified widths:

<link href="SpryAssets/SpryMenuBarHorizontal.css" rel="stylesheet" type="text/css" />
<style type="text/css">
<!--
/* We want to remove any specified width on the menu bar
 * menu items.
 */

ul.MenuBarHorizontal li {
	width: auto;
}

/* Remove any widths on sub menus. */

ul.MenuBarHorizontal ul {
	width: auto;
}

/* We want the menu items in our sub menus to
 * fill up the entire width of the sub menu, so
 * make sure it is display:block and not floated.
 * Also remove any specified width from the default
 * style sheet and turn on "nowrap".
 */

ul.MenuBarHorizontal ul li {
	display: block;
	float: none;
	width: auto;
	white-space: nowrap;
}

/* Now that our menus auto size horizontally, we need to
 * make sure that we have some space for any sub menu indicators
 * so they don't overlap with the text in the menu item.
 */

ul.MenuBarHorizontal a.MenuBarItemSubmenu {
	padding: 0.5em 2em 0.5em 0.75em;
}

-->
</style>

makes things a bit better:

But, now we have a couple of problems:

The IE bug that is very similar to the "Extra Whitespace in List Links bug". But the suggested workarounds don't seem to work. For example, removing all the extraneous white space within the menubar's lists still yields gaps:

 

Also, trying to use the hack of display:inline-block followed by display:block to turn on hasLayout causes the layout to totally break-down. The only workaround we've been able to find for this problem is to place a border-bottom on the element, so as a workaround, we will add a border-bottom to our menu item <li> elements that is the same color as the background of the menu, so it blends in with the background:

<link href="SpryAssets/SpryMenuBarHorizontal.css" rel="stylesheet" type="text/css" />
<style type="text/css">
<!--
/* We want to remove any specified width on the menu bar
 * menu items.
 */

ul.MenuBarHorizontal li {
	width: auto;
}

/* Remove any widths on sub menus. */

ul.MenuBarHorizontal ul {
	width: auto;
}

/* We want the menu items in our sub menus to
 * fill up the entire width of the sub menu, so
 * make sure it is display:block and not floated.
 * Also remove any specified width from the default
 * style sheet and turn on "nowrap".
 */

ul.MenuBarHorizontal ul li {
	display: block;
	float: none;
	width: auto;
	white-space: nowrap;
	border-bottom: solid 1px #EEE;
}

/* Now that our menus auto size horizontally, we need to
 * make sure that we have some space for any sub menu indicators
 * so they don't overlap with the text in the menu item.
 */

ul.MenuBarHorizontal a.MenuBarItemSubmenu {
	padding: 0.5em 2em 0.5em 0.75em;
}

-->
</style>

makes things a bit better in IE:

But we still have the problem in Mozilla/FireFox. When the text within a menu bar menu item is wider than any of the text in its sub menu, the <li> elements of the sub menu render with collapsed widths so the menu items no longer span the entire width of the sub menu. This bug seems to be triggered by the fact that the menu items in the menu bar are float:left. You will notice that The first and fourth menus in the example above exhibit this problem, but none of the sub menus of sub menus exhibit this problem.

The only way we've been able to get around this bug is by either specifying a width on the affected sub menu's <ul>, or by padding out the longest string in the sub menu with non-breaking spaces till its width exceeded that of the menu bar menu item.