[whatwg] Menus, fallback, and backwards compatibility: ideas wanted

Matthew Raymond mattraymond at earthlink.net
Tue Nov 29 03:25:18 PST 2005

Lachlan Hunt wrote:
> Ian Hickson wrote:
>>On Mon, 28 Nov 2005, Lachlan Hunt wrote:
>>>How about this, or some variation of:
>>><form ...>
>>>  <li><button type="submit" for="foo" name="menu">Foo</button>
>>>      <select id="foo" name="foo">
>>>        ...
>>>      </select>
>>>  </li>
>>>  ...
>>Interesting idea. I like the non-JS fallback potential. Pity about the 
>><menubar> being necessary to get the <select> to disappear, but I guess 
>>we need that...

   If we must exclude the use of actual menu bars, I'd prefer the following:

| <nav>
|   <form ...>
|     <menulabel>
|       <menu>
|         <select>
|           ...
|         </select>
|       </menu>
|       <button type="submit" name="menu">Foo</button>
|     </menulabel>
|     <menulabel>
|       ...
|     </menulabel>
|   </form>
| </nav>

> I originally just used <menu>, which is why the <li>s are there, but I'm 
> not sure if its really is necessary.  Couldn't the for attribute used to 
> associate the button with the the select, be used to determine how to 
> render the controls without the menu/menubar/etc. wrapper?
>>It's unfortunate about the button being first, too.
>  From an implementation perspective, is there any reason why it couldn't 
> work with the order of the button and select elements swapped?  At the 
> moment, I thinking it should work if the button and select are just 
> immediate siblings of each other in any order, though I'm not sure if it 
> should work if there were other content in between.

   I'm not sure I like the whole <menubar> scenario. With <menulabel>
(as you will see below), certain child markup is ignored, whereas
<menubar> is actually changing the semantics of the child markup.
Overloading and selectively altering the semantics of elements should be
avoided whenever possible.

>>I guess we could change that if we say that in the new world in an <li> any 
>><select>s are ignored and just the <button> is looked for... Hmm.
> I'm not sure I understand.  Wouldn't that break many existing documents 
> which do have select and buttons inside li elements?  What if it were 
> done like this:
> <label>
>    <button for="foo">Foo</button>
>    <select id="foo">
>      ...
>    </select>
> </label>
> or
> <label>
>    <select id="foo">
>      ...
>    </select>
>    <button for="foo">Foo</button>
> </label>

   If you interpret <button> as being a form control, then in the former
the <label> would be associated with the <button>, where in the latter
it would be associated with the select. Personally, though, I think this
makes more sense:

| <label for="foo"><button>Foo</button></label>
| <select id="foo">
|   ...
| </select>

   The <button> is not associated with the <label> because the |for|
attribute explicitly defines the association as being with the <select>.
Therefore, <button> can inherit the <label> association without adding a
|for| attribute to it.

> In these cases, the button is acting as the label for the select menu 
> which makes sense semantically and it probably wouldn't require any 
> extraneous <menu[bar]> markup.  There is, however, still the extra |for| 
> attribute, but I think it (or something similar) is necessary so that we 
> don't inadvertently break any existing documents that do have buttons 
> and selects together in a label element.

   I think we should focus on how to create solutions that allow optimal
fallback rather than trying to support a broad range of suboptimal
fallback options. Two controls shouldn't be inside a <label> to begin
with, and considering how underused <label> is, I doubt such markup is

> Alternatively, we could ditch the |for| attribute and substitute another 
> element for label or, if possible, do as I suggested above and just use 
> the |for| attribute to associate them regardless of their 
> parent/ancestor elements.

   Perhaps this:

| <menulabel for="foo"><button>Foo</button></menulabel>
| <menu>
|   <select id="foo">
|     ...
|   </select>
| </menu>

   The <menulabel> would ignore the <button> in the same way I defined
it as ignoring <a> elements. The contents are kept, but the element
itself is ignored.

   Similarly, this is another solution:

| <menulabel>
|   <menu>
|     <select>
|       ...
|     </select>
|   </menu>
|   <button>Foo</button>
| </menulabel>

   Again, the contents of <button> are used for the menu label, but the
<button> itself is ignored. The <select> is recognized as menu markup
and implicitly associated with the menu label.

   For situations where the button isn't used, you can just drop it:

| <menulabel>Foo
|   <menu>
|     <select>
|       ...
|     </select>
|   </menu>
| </menulabel>

   Note that I am reusing the idea that <menu> can accept <option>
elements, and that it ignores the containing <select> element. Because
it accepts <option> children and ignores <select>, it doesn't actually
change the semantics of the elements, with the exception that <option>
has different semantics when a child of <menu>. Is that a problem?
Should we just treat <select> elements associated with <menulabel>
elements as menus and simplify the markup?

| <menulabel>
|   Foo
|   <select>
|     ...
|   </select>
| </menulabel>

  Then again, with some creative interpretation, we could consider the
<menulabel> to be displaying a select with a menu presentation and a
submit-on-activation behavior. Hmm...

More information about the whatwg mailing list