Auto Width Vertical Menu Bar

This page shows you how to modify the default styles for a Vertical 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 also have to work around a specific IE layout bug.

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 Vertical Menu Bar looks like:

But when you start using long strings in both the menu bar and sub menus:

The menu items in both the menu bar and its submenus 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="../../widgets/menubar/SpryMenuBarVertical.css" rel="stylesheet" type="text/css" />
<style type="text/css">
<!--

/* Remove the fixed width off the menu bar itself. We float
 * the menu bar so that the browser sizes its width just enough
 * to fit its content. Another option, would be not to float the
 * menu bar, which will allow it to expand horizontally to fill
 * what ever container it is in.
 */

ul.MenuBarVertical {
	width: auto;
	float: left;
}

/* We want our menu items to expand to fill up its container,
 * so make sure it is a non-floated block element.
 */

ul.MenuBarVertical li {
	width: auto;
	display: block;
	float: none;
}

/* Remove any widths on sub menus. */

ul.MenuBarVertical ul {
	width: auto;
}

/* We don't want the text in any of our sub menus to
 * wrap, so we need to turn on "nowrap".
 */

ul.MenuBarVertical ul li {
	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.MenuBarVertical a.MenuBarItemSubmenu {
	padding: 0.5em 2em 0.5em 0.75em;
}

-->
</style>

makes things a bit better:

But, now we have a problem in IE. The menu bar and sub menus now have white gaps between the menu items! This IE bug is very similar to the "Extra Whitespace in List Links bug", but the suggested workarounds don't seem to work as demonstrated in the "Auto Width Horizontal Menu Bar Sample". 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="../../widgets/menubar/SpryMenuBarVertical.css" rel="stylesheet" type="text/css" />
<style type="text/css">
<!--

/* Remove the fixed width off the menu bar itself. We float
 * the menu bar so that the browser sizes its width just enough
 * to fit its content. Another option, would be not to float the
 * menu bar, which will allow it to expand horizontally to fill
 * what ever container it is in.
 */

ul.MenuBarVertical {
	width: auto;
	float: left;
}

/* We want our menu items to expand to fill up its container,
 * so make sure it is a non-floated block element.
 *
 * The bottom border property is used here as a hack around
 * an IE6 bug that causes white gaps to appear between positioned
 * elements when a class is programatically placed on one of them,
 * even if that class is not defined, or contains no CSS properties
 * that have any visual impact.
 */

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

/* Remove any widths on sub menus. */

ul.MenuBarVertical ul {
	width: auto;
}

/* We don't want the text in any of our sub menus to
 * wrap, so we need to turn on "nowrap".
 */

ul.MenuBarVertical ul li {
	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.MenuBarVertical a.MenuBarItemSubmenu {
	padding: 0.5em 2em 0.5em 0.75em;
}

-->
</style>

makes things a bit better: