openui / open-ui

Maintain an open standard for UI and promote its adherence and adoption.
https://open-ui.org
Other
3.58k stars 191 forks source link

[selectmenu] Mechanism to use <select> as progressive enhancement? #648

Closed hidde closed 1 year ago

hidde commented 1 year ago

From: https://home.social/@ranger/109505541067518807

In browsers that don't support <selectmenu>, you could do something like this to fallback to <select>:

<selectmenu>
  <select>
  …</select>
</selectmenu>

(A bit, but probably not the same, like how you could put fallback content in a <video>)

Should there be a mechanism, when browsers do support <selectmenu>, that they ignore any nested <select>s and assume they are only there as a fallback? Would that even be a safe assumption to make?

brechtDR commented 1 year ago

Creating something like this would definitely be beneficial.

Personally, I think that when a developer chooses to use a selectmenu, it will be with the latest browsers in mind and thus could be ignored. But as I stated, that's just my opinion.

In any case, it would make fallbacking a lot easier and could result to faster adaption and reduce of polyfills.

The only thing I'm not sure about is that this could potentially overcomplicate the usage of built in ui. For example: making the selectmenu show the android popup selector or iphone select wheel when on mobile, while having a styled version on desktops.

Sidenote though: Both should be easy to target with JS (something that targets both cases) especially for bigger filter menus.

css-meeting-bot commented 1 year ago

The Open UI Community Group just discussed [selectmenu] Mechanism to use <select> as progressive enhancement?.

The full IRC log of that discussion <gregwhitworth> Topic: [selectmenu] Mechanism to use <select> as progressive enhancement?
<gregwhitworth> github: https://github.com/openui/open-ui/issues/648
<scotto> q+
<Brecht_De_Ruyte> q+
<gregwhitworth> masonf: it's a suggestion from hdv that to use <select> inside of a <selectmenu> and if <selectmenu> is supported you'll get selectmenu otherwise an older select
<gregwhitworth> scotto: if it werent' for the fact that selectmenu was for any arbitrary content but for the fact that while would we kick out old select menu. Every other HTML element would be allowed but this one
<gregwhitworth> ack scotto
<gregwhitworth> Brecht_De_Ruyte: I commented on the issue as well
<gregwhitworth> ack Brecht_De_Ruyte
<gregwhitworth> Brecht_De_Ruyte: I do think that would lead to quicker adoption and an easy fallback
<gregwhitworth> Brecht_De_Ruyte: some people really need to support older browsers
<masonf> q?
<gregwhitworth> Brecht_De_Ruyte: when you have the selectmenu but you use the default select on your phone, if you want to fallback to that - how would you handle that
<masonf> q+
<gregwhitworth> q+
<gregwhitworth> ack dbaron
<tantek> I like this fallback approach to allow for progressive enhancement.
<gregwhitworth> dbaron: it seems like an interesting and useful idea and you need to be careful at what layer the behavior it happens in
<masonf> q?
<gregwhitworth> dbaron: it may be where all of the options have downsides
<gregwhitworth> ack masonf
<gregwhitworth> masonf: that's a good point, there may be some parser issues or edge cases, etc. It may be difficult
<gregwhitworth> masonf: maybe there is another way to do it
<tantek> +1 dbaron you have to pick where the "ignoring" happens, parse time, or later or .??
<scotto> +1 that it's a good idea to figure out how to do a fallback. i don't disagree with wanting to do that at all.
<gregwhitworth> masonf: Brecht_De_Ruyte mentioned an open issue about being able to opt-in to the native solution
<gregwhitworth> ack gregwhitworth
<tbondwilkinson> q+
<gregwhitworth> ack tbondwilkinson
<gregwhitworth> tbondwilkinson: you have the support selector, without something like that in selectmenu - it feels like it's missing a generalized solution to this
<gregwhitworth> q+
<gregwhitworth> ack gregwhitworth
<gregwhitworth> Good summation by masonf that we agree we do need a PE solution but don't agree on how to do it
<gregwhitworth> Zakim, end meeting
<Zakim> As of this point the attendees have been masonf, flackr, smaug, dbaron, sarah_higley, Brecht_De_Ruyte, tbondwilkinson, scotto, tantek, chrishtr, gregwhitworth, Aneta
<Zakim> RRSAgent, please draft minutes
<Zakim> I am happy to have been of service, gregwhitworth; please remember to excuse RRSAgent. Goodbye
<RRSAgent> I have made the request to generate https://www.w3.org/2023/01/12-openui-minutes.html Zakim
mfreed7 commented 1 year ago

So the conclusion of the meeting above was that we generally agree that there should be a progressive enhancement mechanism for <selectmenu> but we're unclear what it should be. Nested <select> likely has some parser issues, because not all content is allowed inside <select>. There was a comment (that I agree with) that perhaps HTML needs a better way of feature detection, akin to CSS's @supports.

The action item here is to suggest a way forward that provides progressive enhancement.

josepharhar commented 1 year ago

Sidenote though: Both should be easy to target with JS (something that targets both cases) especially for bigger filter menus.

You should be able to do this by checking window.HTMLSelectMenuElement, right?

josepharhar commented 1 year ago

The action item here is to suggest a way forward that provides progressive enhancement.

I think that a javascript polyfill like this is good enough: https://jsfiddle.net/jarhar/hdsfpnzj/

if (!window.HTMLSelectMenuElement) {
  document.querySelectorAll('selectmenu').forEach(selectmenu => {
    const select = document.createElement('select');
    while (selectmenu.children.length) {
      select.appendChild(selectmenu.firstChild);
    }
    selectmenu.after(select);
    selectmenu.remove();
  });
}

I could also add some more code to copy attributes from the selectmenu to the select

hidde commented 1 year ago

When thinking about progressive enhancement, I think the other way around, eg what would a browser do that doesn't know what a selectmenu is?

With something like

<selectmenu>
  <select>
  </select>
</selectmenu>

I would expect a browser that doesn't know about selectmenu would throw that wrapping selectmenu tag out and/or ignore it, and then it would just render the select inside, with no JS needed to get that behaviour. Then a browser that does know what selectmenu is, would throw any select element inside of it out, as it knows that that is a fallback.

The use of this is probably limited, especially with more advanced use selectmenu use cases. But one “common” use case I can think of is someone who uses selectmenu just for the purposes of styling. They would prefer to use selectmenu so that they can style it, and that would work as advertised in any selectmenu-supporting browser in the future, but at the same time, they could live with an unstyled/default styled select in older bowser versions.

josepharhar commented 1 year ago

I would expect a browser that doesn't know about selectmenu would throw that wrapping selectmenu tag out and/or ignore it, and then it would just render the select inside

It would seem that this currently works, which is good because I think we would have a hard time getting safari and firefox to implement this selectmenu-specific behavior

Then a browser that does know what selectmenu is, would throw any select element inside of it out, as it knows that that is a fallback

This does not currently work, it creates a select element in the selectmenu's dropdown. So I guess that the request is to make selectmenu skip select elements...?

Nested <select> likely has some parser issues, because not all content is allowed inside <select>

So even if we did make selectmenu try to skip child select elements, it sounds like there could be additional issues and would at least be complicated to put into the browser. I still think that some javascript which turns selectmenu elements into select elements is best.

hidde commented 1 year ago

It would seem that this currently works, which is good because I think we would have a hard time getting safari and firefox to implement this selectmenu-specific behavior

I don't know specifics of how this works, but my understanding is “unknown tags are ignored” is generally how HTML is handled across browsers?

This does not currently work, it creates a select element in the selectmenu's dropdown. So I guess that the request is to make selectmenu skip select elements...?

Yes! I feel it would make sense.

Nested

So even if we did make selectmenu try to skip child select elements, it sounds like there could be additional issues and would at least be complicated to put into the browser.

Would be curious to learn more about the mechanics here!

I still think that some javascript which turns selectmenu elements into select elements is best.

While progressive enhancement doesn't necessarily mean “no JavaScript”, to me requiring JS for backwards compatibility would be less desirable than having some built-in mechanism for provide a fallback for a non-supported feature in non-supporting browsers.

mfreed7 commented 1 year ago

Slight improvement to the JS solution:

if (!window.HTMLSelectMenuElement) {
  document.querySelectorAll('selectmenu').forEach(selectmenu => {
    const select = document.createElement('select');
    select.replaceChildren(...selectmenu.childNodes);
    [...selectmenu.attributes].forEach(attr => {
      select.setAttribute(attr.nodeName,attr.nodeValue)
    });
    selectmenu.after(select);
    selectmenu.remove();
  });
}
css-meeting-bot commented 1 year ago

The Open UI Community Group just discussed [selectmenu] Mechanism to use as progressive enhancement?, and agreed to the following:

The full IRC log of that discussion <gregwhitworth> Topic: [selectmenu] Mechanism to use as progressive enhancement?
<gregwhitworth> github: https://github.com/openui/open-ui/issues/648
<gregwhitworth> q+
<hdv> jarhar: the request here is to make it easy to fallback to the <select> tag in browsers that dont support <selectmenu>, so that <select> would get ignored in newer browsers but used in older ones
<masonf> q+
<hdv> q+
<scotto> q+
<hdv> jarhar: in the issue I provided a polyfill that would take options from a selectmenu and then put them into a select element
<gregwhitworth> ack gregwhitworth
<hdv> gregwhitworth: I'm not a fan of this because people using <selectmenu> will likely end up nesting a lot of things, I am assuming the browser will end up throwing that content away
<hdv> masonf: I think that's part of the question
<bkardell_> q+ to ask why you would want select menu if you weren't using slots, etc?
<hdv> gregwhitworth: I think select and selectmenu are too different in order for this kind of fallback to actually work in reality
<dandclark> +1, the simple nesting approach will result in a big mess due to `<select>` parsing rules. Polyfill is needed.
<gregwhitworth> ack masonf
<hdv> masonf: I like the idea… if there was an easy to polyfill it , which this way seems to be… doing this in the parser I could see lots of issues
<hdv> masonf: the way to do it for the parser would probably to skip select entirely
<masonf> q?
<gregwhitworth> ack hdv
<gregwhitworth> hdv: what I was thinking about is the usecase where you use selectmenu where you just want to style something
<gregwhitworth> hdv: nothing fancy, in that case I can imagine it would work but I didn't think of the other usecases so I can see why this wouldn't really work
<gregwhitworth> hdv: the polyfill, it isn't PE but graceful degradation
<gregwhitworth> hdv: the reason I thought of this is that it's the simplest way
<gregwhitworth> q+
<gregwhitworth> hdv: maybe we add really strict rules around it when it's only styles
<dbaron> (I also wonder if you could polyfill selectmenu (into select) with webcomponents, for these use cases.)
<gregwhitworth> ack scotto
<hdv> scotto: if this was a 1:1 replacement with select to selectmenu I would see this working… but just the fact that anyone can put anything into these options, there is not going to be any simple fallback
<hdv> scotto: like if you have a button inside an option… if that falls back to just text, then we would get garbage form content submitted
<hdv> scotto: only in a very simple use case like that hdv mentioned with 'just' text' I could see it work, but in pretty much every other case it would create more problems than it solvs
<hdv> s/solvs/solves
<gregwhitworth> ack bkardell_
<Zakim> bkardell_, you wanted to ask why you would want select menu if you weren't using slots, etc?
<hdv> bkardell_: the question I was going to ask, if you're not using slots, why would you use selectmenu? how is it better?
<bkardell_> https://github.com/whatwg/html/issues/4696
<hdv> bkardell_: I think this could use some holistic talk, not just about this
<hdv> bkardell_: when we were talking about panelset we had similar questions about progressive enhancement
<hdv> xiaocheng: I also think it would add too much trouble if we add this kind of progressive enhancement. This should probably be something done by polyfill, like the few lines that jarhar posted
<hdv> xiaocheng: so I think we should consider this to be something to polyfill
<flackr> q+
<jarhar> Proposed resolution: Don't support nesting select tags inside selectmenu tags as a progressive enhancement
<gregwhitworth> ack gregwhitworth
<hdv> gregwhitworth: ok, we can put forward a proposed resolution, I think we should come up with a genearl approach
<gregwhitworth> ack flackr
<hdv> s/genearl/general
<hdv> flackr: the fallback if a browser doesn't have a feature isn't always as simple as providing a fallback… you can easily polyfill fallback to a plain selectmenu or chose to make it more fancy. It gives more options and better fallback behavior than something like a text only selectmenu thing. You could make the same argument for dialog
<hdv> gregwhitworth: I could totally see our design system team use the component we already have as a fallback for selectmenu
<masonf> +1
<hdv> +1
<dandclark> +1
<hdv> bkardell_: you can transform HTML element that seems similar for a user, but it is definitely not polyfilling
<hdv> flackr: but developers can do better than we can as a browser
<jarhar> RESOLVED: Don't support nesting select tags inside selectmenu tags as a progressive enhancement
<hdv> JakeA: where can I learn about <selectmenu> in its latest state?
<hdv> [ discussion of WHATWG PR vs explainer and keeping explainer updated vs blog post on CSS Tricks ]
<hdv> github: foo
hidde commented 1 year ago

This was just discussed and resolved not to (see minutes in comment above).

TLDR: beyond the simplest use case of auomatigally making this work for text-only options (which is also trivial to do client side with the few lines of JS above), doing it for more complex cases is impossible to do realibly and developers will likely be in a better position to provide sensible a fallback, eg with a divs based component their design system already has.