The Trouble With ASP.NET Menu
In older versions of ASP.NET the menu control and Treeview control rendered as a set of nested html table elements with lots of hard coded inline styles, it was not a very semantic way to markup a menu. After ASP.NET 2.0, Microsoft came out with the CSSAdapters to adapt the Menu and Treeview controls to produce a nicer set of ul and li elements which is much better structure for a menu. We have used those adapters modified to meet our needs, and we made our own mojoMenu and mojoTreeview controls which inherit from <asp:Menu and <asp:Treeview respectively, but also applies the CSS Adapters and lets us have more control over the markup rendered by the menu and treeview.
In ASP.NET 4 there were additional changes to the <asp:Menu such that now there is some javascript associated with the Menu, and this javascript adds some inline style and as far as I can determine there is no way to disable that javascript. Since our mojoMenu inherits from the ASP.NET menu it also has this unwanted javascript. Questions about this have come up over and over in the forums so I decided it was time to write a document about it so that I can link to it whenever the question comes up.
When you view the source of the page you will not see the extra style because it is applied from javascript, so the only way you can see it is to use something like Firebug to inspect the html after the javascript has modified it. What you will find is things like:
- ul elements have style="position: relative; width: auto; float: left;"
- li elements have style="position: relative; float: left;"
These things can interfere with your own CSS rules and have unintended consequences that are contrary to your design goals.
There are 3 possible approaches to solving the problem.
- You can configure the Menu to behave as it did in .NET 3.5 by this setting from theme.skin:
<portal:mojoMenu runat="server" SkinID="SiteMenu"
UseNet35Mode="true"
/> The only down side to this solution is that we lose one benefit of the.NET 4 menu. The .NET 2/3.5 Menu always renders a style block at the top of the page and this can also work against your intended styles. In .NET 4 the Menu has a property IncludeStyleBlock that you can set to false to eliminate the style block, but when you configure it to behave like .NET 3.5 it ignores this setting.
- You could try using TreeView instead of Menu since it also renders as a list and it does not have javascript that applies style.
- You can use the !important in your CSS rules to override the inline style rules that interfere with yours.
- You might be able to write some javascript that runs after the menu script and remove those hard coded styles.
- As of mojoPortal version 2.3.9.5 you can also use FlexMenu as an alternative that does not use the ASP.NET Menu or TreeView
For example if the float:left is causing you a problem which is very common when designing for right to left languages, you can overcome (using approach number 3) it by marking your css rules as important like this:
.AspNet-Menu-Horizontal {float:right !important;}
.AspNet-Menu-Horizontal ul li {float:right !important;}
That should work in most modern browsers but might not work in older versions of some browsers. If you need to support older browsers you could use a Treeview or, you could possibly devise some javascript of your own that runs after the menu is initialized and then remove the inline style that was added by the menu javascript.
Update: See this forum post by Thomas Lilly for another possible approach to this problem that involved replacing the menu script with an empty file.
Last Updated 2011-12-19 by Joe Audette