[whatwg] [WA1] Quick thoughts on menus.

Matthew Raymond mattraymond at earthlink.net
Mon Oct 17 11:21:11 PDT 2005


Ian Hickson wrote:
> On Sun, 16 Oct 2005, Matthew Raymond wrote:
>>[...] Also, my model doesn't allow menus to be displayed via a 
>>hyperlink. Displaying menus via hyperlink would introduce weird 
>>situations like bookmarking menus and referencing menus outside the 
>>document. While it may be possible to create a set of rules to deal with 
>>these various problems, I believe my <menulabel> solution to be far 
>>simpler and easier to learn. [...]
> 
> I'll take a closer look at this in a few months when I rewrite the menu 
> section, but I just wanted to jump in here to give some context for people 
> who do wish to come up with a better model than what is currently in the 
> spec (and heck knows we need one).
> 
> There are several key things that this part of the spec is trying to 
> achieve, and several things which are "nice to haves" which we should aim 
> for but which should not constrain the design.
> 
> Requirements:
> 
>  * The design should be related to the way people do DHTML menus on sites 
>    today. Either it should be possible to easily annotate existing markup
>    and get native menus out of them, or it should be possible to easily 
>    get older UAs to render the new menus in the old way, or something of 
>    a real migration story.

   I'm not so sure. Certainly, the menus need to degrade gracefully, but
I'm not convinced that menu-related markup can be designed in such a way
that fits every type of DHTML menu. Heck, some menus are CSS based with
some HTC to make them work on IE6. The point of menu markup in HTML5
shouldn't be to support every kind of existing legacy menu technique,
but rather to allow menus to be created in a way that can easily be
supported on legacy clients via a little styling and Javascript.

   Compare www.adobe.com, www.nvidia.com, www.ati.com and www.opera.com.
Adobe's site uses |onmousein| and |onmouseout| to show and position
<div> elements located in a part of the document separate from the menu
markup. The fallback is that you can click the <a> element to go to the
highest level webpage related to the menu label.

   ATI does something similar.

   Nvidia is similar, except that the <div> elements are siblings of the
<a> elements, and the <div> elements include tables for item positioning.

   Opera has only a list-based navigational bar in the HTML, but builds
the menus using Javascript.

   The common use case I'm seeing here is that you have an <a> element
with the menu label, but the |href| attribute NEVER points to the
element containing the menu. Instead, it points to a page that is
essentially a more detailed version of the submenu. (In other words,
clicking on the top-level menu label "Products" takes you to the
products page rather than showing the products menu in the menu bar.)
Activation of the menus always seems to be done via |onmousein| and
|onmouseout|. The element containing the menu items for each menu in the
menu bar are NEVER children of <a> element.

   Now, granted, this is a limited selection of sites that use menus,
but since the <a> element used in the menus never actually links to a
menu, I don't see how using <a> to display menus is useful for fallback
on legacy user agents.

   (Oddly, it strikes me that these menus should be possible with CSS.
It's probably to get around problems with Internet Explorer not properly
 supporting :hover.)

>  * Same with the way people do <select> menus.

   Preaching to the choir in my case. I practically invented the idea:

http://listserver.dreamhost.com/pipermail/whatwg-whatwg.org/2004-June/000421.html

   Not sure I like wrapping the <select> in a <menu>, though, but at the
moment I can't really think of a more elegant alternative, considering
the fact that we need the submit button for browsers that don't support
Javascript.

> These two points are the cause of the way the current proposal handles <a> 
> and <select> specially.

   I see no cause for special handling of <a>. My version of <menulabel>
can accomplish the same thing without changing the nature of <a>:

| <menulabel for="myMenu"><a href="#myMenu">My Menu</a></menulabel>
| <menu id="myMenu"></menu>

   In fact, <menulabel> provides a better fallback case:

| <menulabel for="menuProducts">
|   <a href="products/index.html">Products</a>
| </menulabel>
| <menu id="menuProducts"></menu>

   The implication is that if the UA supports <menulabel>, hyperlinks
inside the <menulabel> are ignored, which is something I've suggested
earlier. The <menulabel> element also allows for the simulation of
buttons with optional dropdown menus:

| <div class="dropdownbutton">
|   <a href="products/index.html">Products</a>
|   <menulabel for="menuProducts">
|     <img src="dropdown.png" alt="[v]">
|   </menulabel>
| </div>
|
| <menu id="menuProducts"></menu>

   (Not sure what to do about menus where you hover over the parent to
get the submenu. That can be done on browsers with proper CSS support
right now, so I question adding special support for it.)

>  * It must be possible to do context menus with this system. This implies 
>    getting data like mouse X/Y position, getting target element 
>    information, having a way to update the context menu based on where it 
>    was called from, etc.
> 
> This is really badly handled at the moment.

   Are special event attributes in order? An "oncontextmenu" event
attribute, perhaps, that has arguments that identify the target element?

>  * The feature must support a way to keep toolbar buttons and menu items 
>    in sync regarding things like disabled state, radio button selection, 
>    icons, etc.
> 
> This last requirement is the source of <command> et al. IMHO this works 
> reasonably well as currently specified.

   Pretty much. I'd like to see a solution where it's possible to do
checks and radio buttons in menus using <menu> and <li>, in addition to
the features of <command>.

>  * A balance between ease of authoring, ease of implementation, ease 
>    of specification, ease of testing, etc.
> 
> Nice to haves:
> 
>  * It could be possible to have a stand-alone HTML "document" that has a 
>    native menu bar in stand-alone mode, and have that same document work
>    fine in a non-trusted environment (i.e. a Web browser content area).
> 
> <menubar> was supposed to help with this, but IMHO fails to do it in a 
> sane way.

   This goes well beyond choice of markup. The <menubar> definition
isn't the problem so much as how and if we allow native menu bars in the
browser at all. That's why I went for the idea of a <nav> that simulates
a menu bar. It allows you to create what is effectively a menu bar, but
at the same time it completely side-steps the debate.

>  * It should be possible to have this fallback to a sane rendering even in 
>    Lynx, where instead of scripting to do the commands, you'd have a list 
>    of items and have things happen server side.
> 
> This was the thinking behind using <menu> <li>.

  And you'll see that my solution allows <menu><li>-based menus.

>  * Should be possible to share menus, e.g. to have one drop-down menu 
>    shared between a toolbar button and a context menu without having to 
>    list it twice.
> 
> The current proposal does this, though not that intuitively IIRC.

   My version of <menulabel> allows you to do this using the |for|
attribute. HTML 4.01, as I understand, allows more than one <label> to
be associated with a control using |for|.

>  * Should be possible to have menus drop down from buttons (the way that
>    <select> is often abused today for doing commands, e.g. in GMail; 
>    this kind of UI is seen a lot in native applications on all platforms).
> 
> I don't remember if this is possible in the current proposal.

   The default rendering for a <menulabel> element that is not the child
of a <menu> could be a button.

> Non-requirements:
> 
>  * Script-free. There's no reason to design this in a way that it doesn't 
>    require script somewhere to do it. (Though of course, cutting down on 
>    script is always good if it is replaced by something simpler.)

   Script should not be required for the menu itself at all. It should
only be needed for the actions that occur when a menu item is activated.
Menu markup should never result in unnecessary accessibility issues
involving Javascript.

>  * Replicate every feature of every OS in the first version.

   Yeah, that would be somewhat silly. As it stands, current proposals
include most of what's supported out there.

>  * Having arbitrary form controls in menus.

   Actually, I'd like to be able to use things like <input
type="check">, <input type="radio"> and <img> in menus created using
<menu><li>. We could have specific rules for which elements are permitted.

>  * Introducing no new elements. It's ok to introduce new elements.

   New elements should be kept to a minimum, although I think we're
pretty much doing that already. Still, it would be possible to do the
whole thing with no new elements. In fact, we could use a microformat:

| <div class="nav">
|   <label class="menulabel">File
|     <menu class="menu" id="menuFile">
|       <li>
|         <label class="menulabel">Downloads
|           <menu class="menu" id="menuDownloads">
|             <li><a href="source.html">Source Code</a></li>
|             <li><a href="wallpaper.html">Wallpaper</a></li>
|           </menu>
|         </label>
|       </li>
|       <li><hr></li>
|       <li><a href="exit.html">Exit</a></li>
|     </menu>
|   </label>
|   <a href="help.html">Help</a>
| </div>
|
| <form action="redirect.cgi">
|  <div class="menubar">
|   <label class="menulabel" for="goto">Go to...</label>
|   <select class="menu" id="goto"
|           onchange="if (this.options[this.selectedIndex].value)
|                     window.location =
|                     this.options[this.selectedIndex].value">
|    <option value="" selected="selected"> Select site: </option>
|    <option value="http://www.apple.com/"> Apple </option>
|    <option value="http://www.mozilla.org/"> Mozilla </option>
|    <option value="http://www.opera.com/"> Opera </option>
|   </select>
|   <input class="menusubmit" type="submit" value="Go">
|  </div>
| </form>

   I don't like it, but you can see that it's possible.

   Note that right now, my menu scheme depends on <menu> elements
associated with a <menulabel> being hidden in HTML5 user agents when
they don't have focus. I'd prefer that there be markup to specifically
identify a <menu> as a menu rather than forcing the web author to search
the page for a corresponding <menulabel>. Perhaps something like this:

| <menulabel for="menuProducts">
|   <a href="products/index.html">Products</a>
| </menulabel>
|
| <menu popup id="menuProducts">[...]</menu>
|
| <menu id="legacyMenu">
|   <li>Item 1</li>
|   <li>Item 2</li>
|   <li>Item 3</li>
| </menu>

   A better name for the attribute is probably in order, but you get the
idea.



More information about the whatwg mailing list