open-ui icon indicating copy to clipboard operation
open-ui copied to clipboard

[select] Should the inner HTML & styles of the selected option be copied into selected-value?

Open clarumedia opened this issue 1 year ago • 24 comments

Chrome 103.0.5060.114

When an option is "selected" using the "selected" attribute, shouldn't the style of that option supersede the style of the select ? Use case: colours set on select options via CSS, the selected colour would display having been selected.

<select>
	<option style='color:blue;' >1 Blaa x</option>
	<option style='color:red;' selected >I would expect the collapsed select control to be red because this is the selected option</option>
	<option style='color:green;' >3 Blaa more</option>
</select>

clarumedia avatar Jul 20 '22 15:07 clarumedia

@clarumedia this is a solid thought; however, this isn't specified as it relates to the base styling for <select> since that is left to the UAs and they're technically different elements. So while they often appear as one set of elements the options are actually not what's being rendered but what is being reflected. This is however one good thing of the new <selectmenu> that we're working on as you can now achieve this and also see how this anatomy exists in this pen: https://codepen.io/gregwhitworth/pen/XWEBLwe

Now you could argue that you'd like <selectmenu> to do this to appear as though it's truly reflecting the content within the option and that's worth considering although I can think of arguments for not doing this by default and leaving it for the author to do. Interested to get your thoughts as well as @dandclark. This is a usecase worth thinking about because options can now have arbitrary content/styles and I'm curious if common examples clone and reflect all content or just the value.

gregwhitworth avatar Aug 11 '22 00:08 gregwhitworth

@gregwhitworth One thought is a CSS directive or attribute for the selectmenu tag that would tell it to incorporate the CSS of the selected child. Sort of reverse inheritance from the selected item. I can see this could potentially get messy if the child does things like expand horizontally or vertically (for example). Perhaps if we could specify which CSS attributes could effectively be "inherited" from the selected child back to the parent ? Something like:

select { color: inherit-selected; }

clarumedia avatar Aug 11 '22 08:08 clarumedia

The Open UI Community Group just discussed [select] Inconsistent CSS handling when the "selected" attribute has been set on an option ?.

The full IRC log of that discussion <gregwhitworth> Topic: [select] Inconsistent CSS handling when the "selected" attribute has been set on an option ?
<gregwhitworth> github: https://github.com/openui/open-ui/issues/571
<hdv> gregwhitworth: this one was about the current select menu… a lot of this is about the contents of an option… should there be a default expectation of how much is reflected? should it include styles? or even all of the contents?
<tantek> could see both, e.g. icons/content and text/bg colors
<hdv> gregwhitworth: if I have a picker with a name and title below… I could have a CSS grid, but the value could just be my name… do we put the entire contents or just my name?
<hdv> gregwhitworth: I know there are use cases where people clone the entire element
<masonf> q+
<hdv> gregwhitworth: and you could do that today
<gregwhitworth> ack masonf
<hdv> gregwhitworth: wanted to hear people\;s thoughts on when reflection should occur
<hdv> masonf: I think we could do this with imperative slotting, if we added a slot to the anatomy of the default button, and assign the select option to that slot
<scotto_> q+
<hdv> masonf: that would get tricky but it would be doable
<gregwhitworth> ack scotto_
<tantek> do any existing UI frameworks support this kind of style hoisting behavior?
<hdv> scotto_: I think people people would the selected text reflect the value… I could see use cases where people would want to do something like that?
<hdv> scotto_: especially looking at how complex these options could get… so that button elements don't get put inside of the selected
<masonf> q+
<hdv> scotto_: allowing everything to be posted in the value of the combobox has some potential breaking issues to it
<gregwhitworth> q+
<gregwhitworth> ack masonf
<hdv> scotto_: even on a smaller scale, if someone selects a value and wants to style the combobox based on that selected value, that should definitely be allowed
<hdv> masonf: I agree what scotto_ says would be true… we would be able to do this by slotting in your own button… that alleviates the browser to make those kinds of decisions
<hdv> gregwhitworth: I don't think we need to solve this for V1
<hdv> gregwhitworth: [shares screen to show combobox in Outlook that shows contact suggestions in the 'To: ' field, where contacts have avatars]
<masonf> q+
<hdv> gregwhitworth: I think folks can solve this for themselves now in V1, but want to clarify if we could never fix this?
<gregwhitworth> ack gregwhitworth
<gregwhitworth> ack masonf
<hdv> masonf: I think this is a V-forever question, it would not be possible to change while being backwards compatible
<tantek> q+ to ask if any web UI frameworks support this kind of feature
<gregwhitworth> ack tantek
<Zakim> tantek, you wanted to ask if any web UI frameworks support this kind of feature
<hdv> gregwhitworth: so the question is… and what we all should probably think about… would you bring up all the styles plus text content, or just the text content?
<scotto_> q+
<hdv> tantek: do any existing UI frameworks support this kind of option, to have a 'rich option' more than just plain text, be hoisted up to the selected option?
<hdv> tantek: that is usually a good indicator… if there is we should probably consider it, if not, it would be a steep hill to make the case for this
<una> q+
<gregwhitworth> ack scotto_
<hdv> scotto_: I saw some use cases kind of like that… the content is usually slotted into a different area, usually not the area where somebody actually types… it usually gets slotted somewhere adjacent
<gregwhitworth> q+
<hdv> scotto_: there are instances of something like this happen
<gregwhitworth> ack gregwhitworth
<hdv> una: I think this is more common than we think… in Google Docs and Notion for instance
<hdv> una: your email example reminded me of many examples I saw across the web
<tantek> q+ to agree with icon(img)+text example and maybe this is a pseudo-class use-case too?
<hdv> gregwhitworth: if everyone can please get some use cases in the thread… so that we can discuss if we should spend time on this up front or not
<hdv> gregwhitworth: please do take the time, the issue is linked in IRC
<hdv> gregwhitworth: next week I'll need somebody to chair if anyone is able to chair
<masonf> una: https://github.com/openui/open-ui/issues/571
<gregwhitworth> Zakim, end meeting
<Zakim> As of this point the attendees have been emilio, masonf, miriam, hdv, una, scotto_, flackr, sana, sarah_h_, oluOnline, vicgutt, tantek, dbaron, bkardell_
<tantek> +1 una, agree with icon(img)+text example and maybe this is a pseudo-class use-case too
<Zakim> RRSAgent, please draft minutes
<RRSAgent> I have made the request to generate https://www.w3.org/2022/08/11-openui-minutes.html Zakim
<Zakim> I am happy to have been of service, gregwhitworth; please remember to excuse RRSAgent. Goodbye

css-meeting-bot avatar Aug 11 '22 18:08 css-meeting-bot

The Open UI Community Group just discussed [select] Inconsistent CSS handling when the "selected" attribute has been set on an option ? #571.

The full IRC log of that discussion <hdv> topic: [select] Inconsistent CSS handling when the "selected" attribute has been set on an option ? #571
<hdv> github: https://github.com/openui/open-ui/issues/571
<hdv> JonathanNeal: this one has to do with the `selected` attribute and the style of the selected element being hoisted up
<hdv> JonathanNeal: is Chris on the call?
<hdv> dandclark: it looks in the issue the request was for more use cases
<hdv> dandclark: so looks like we should defer it from the agenda until we have that
<hdv> JonathanNeal: ok let's add it to the next agenda once it is ready
<hdv> dandclark: it's a fairly complex issue

css-meeting-bot avatar Aug 25 '22 18:08 css-meeting-bot

Font selection may also be relevant here. This is from the Font Access API demo. Screen Shot 2022-09-29 at 11 53 56 AM

scottkellum avatar Sep 29 '22 18:09 scottkellum

The Open UI Community Group just discussed Should the inner HTML & styles of the selected option be copied into selected-value?.

The full IRC log of that discussion <gregwhitworth> Topic: Should the inner HTML & styles of the selected option be copied into selected-value?
<gregwhitworth> github: https://github.com/openui/open-ui/issues/571
<hdv> gregwhitworth: technically we've already talked about this issue in the past … what happens today… when you invoke the popup in some form or fashion, give it some options, traverse them and pick an option, the value of that option is inserted both as the 'value' and as the innertext of the 'selected-value' part
<hdv> gregwhitworth: what the person opening the issue was talking about was just the colour, but it got us thinking about should we actually copy the whole computed content in rather than just the value
<hdv> gregwhitworth: so the value itself will remain the option value, but the rendered contents to the end user would become the contents of the option element
<masonf> q+
<hdv> gregwhitworth: this is useful when you have complex content inside of the content… like an avatar with a name, when you select it you might see it as an example
<AlexanderFutekov> q+
<dandclark> q+
<hdv> gregwhitworth: I've tried to find these, all of them converted to a string of text
<hdv> gregwhitworth: i wanted to raise this… I personally would like to resolve that the value itself will be used as the value, but we'll take the innerHTML of the <option> and use that as the HTML of the selected-value part
<gregwhitworth> ack masonf
<hdv> masonf: they have the ability to slot in whatever they want… you already gave some examples of when the selected-value has something slightly different
<hdv> masonf: this does seem risky
<gregwhitworth> ack AlexanderFutekov
<hdv> AlexanderFutekov: in the past I had this use case… I built a dynamic styleguide where you could pick backgrounds and colors, it built the classes to use in CMS… what I needed there was a dropdown that could do rich content
<hdv> AlexanderFutekov: just having a plain string of text cannot describe the visual complexity
<hdv> AlexanderFutekov: it is more complex than a color picker. but it's a use case I had to do
<gregwhitworth> ack dandclark
<hdv> dandclark: I think there are some pitfalls
<masonf> q+
<hdv> dandclark: if we take the innerHTML into the selected-value part, and our goal is also to have the background come along, it would depend on whether it was an inline style… or maybe via a stylesheet, and within that whether it was a class or something else
<hdv> dandclark: things like having an ID on an option would get fuzzy because that would get cloned into the selected-value part
<hdv> dandclark: that said, there are scenarios that would be useful
<hdv> dandclark: for instance if all options had a little icon in them and it would just work
<sarah_h> q+
<hdv> dandclark: having said that, I am a little afraid of this. also, if we do want something like this, should we deepclone the contents rather than spinning up the parser to serialise it out?
<gregwhitworth> ack masonf
<JonathanNeal> I have had a need for deep cloning content, as well.
<JonathanNeal> But not for selectmen.
<gregwhitworth> q+
<hdv> masonf: those are better examples… your ID example is great
<hdv> masonf: there is exactly that demo in the selectmenu demo that we did, a component where you can pick a color and the picked option would take that color… am curious how hard that was to do… if it was hard we should maybe offer something, if it was easy, maybe not
<gregwhitworth> ack sarah_h
<JonathanNeal> But I have needed this kind of cloning anytime I need to “reflect” some light provided value into multiple locations. I can watch changes to the DOM, but any CSSOM would indeed be lost.
<hdv> sarah_h: I had another example… if we have buttons inside of options and they get copied, that is also copied over and could cause issues
<AlexanderFutekov_> q+
<hdv> sarah_h: in my experience building these kinds of things… it is common to have a few things within your options that you _don't_ want to see in your trigger button, in fact I think that's actually more common than that you do want to add things in
<JonathanNeal> q+
<hdv> sarah_h: so I would say it would be better to optimise for the more common case of not cloning everything in… my vote would be to default to string value
<hdv> gregwhitworth: I'm not super concerned with the ID issue, because it would technically be using web components
<hdv> gregwhitworth: re: copying all the contents in but you don't want to see them all… it would be easy to select those in CSS and display none them, I probably will have classnames on them
<masonf> q+
<hdv> gregwhitworth: if it's the other way around, I would need to write JavaScript to actually get the contents in… so if content is copied, easy to hide, if it is not copied, hard to add in afterwards
<hdv> gregwhitworth: will take as an action item to look at the design systems we have listed, will also check out Gmail, Outlook, etc
<gregwhitworth> ack gregwhitworth
<gregwhitworth> ack AlexanderFutekov_
<masonf> q-
<hdv> masonf: I just checked, it is about 3 lines of JS in the selectmenu demo
<AlexanderFutekov_> https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-box-reflect and https://developer.mozilla.org/en-US/docs/Web/CSS/element
<hdv> AlexanderFutekov_: I remember that we might not actually need to clone the DOM, if we want to mirror the styles, I remember two cases, see links above
<sarah_h> q+
<hdv> AlexanderFutekov_: these are two ways where the styles reflect styles of another element in CSS
<hdv> AlexanderFutekov_: one none standard, the other is standard, seems browsers can implement this without copying
<hdv> masonf: I worked on this and it's not pretty
<dbaron> they're also laying out in a different area in many cases
<gregwhitworth> ack JonathanNeal
<hdv> JonathanNeal: we've been talking about content, innerHTML, which has to do with having access to the DOM of it… which is what I was going to comment on… but the issue itself is about styling… were we also discussing ability to access content?
<hdv> gregwhitworth: yes they originally hinted on styles, but then later on wanted to copy complex styles, that made me think what about elements
<hdv> gregwhitworth: so you're totally on topic
<hdv> JonathanNeal: I would separate these two topics… when we discuss having access to the content as far as the DOM nodes, that reminds me of what you would do with a form, grab elements by name and grab a label of an input… a useful utility to go and grab those things
<hdv> JonathanNeal: it seemed like that sort of issue
<hdv> JonathanNeal: that's different than, say, if we allow the content to be in there, when it is announced or read, there is accessibility issues
<hdv> JonathanNeal: and then there's this third thing of reflecting styles from another element. Three issues worth looking at, it might be easier to tackle them separately
<hdv> gregwhitworth: the value itself will always remain a string, so we're not talking about taking innerHTML and making that `element.value`
<hdv> gregwhitworth: what we're talking about is like… a country picker with a flag… effectively currently it does innerText, but if you wanted to see the flags, you would need to manually go in, find the images and then insert it… so I am talking about changing this and making a deepclone instead
<hdv> gregwhitworth: you shouldn't end up with accessbiility issues, if you have them you should have them in your original option already
<hdv> JonathanNeal: I had this exact issue when I was working on Web Components… working on components that expand, like in a tree, like when you expand it you can see the children, you end up with a duality
<hdv> JonathanNeal: even with tabs we ended up in a situation where we almost wanted to double slot things
<hdv> JonathanNeal: if the data binding is possible we could help a lot more use cases… basically take the styles from another element by reference… push its computedStyle to another element
<masonf> q?
<hdv> JonathanNeal: I feel this would be worth taking on and solve problems beyond selectmenu
<gregwhitworth> ack sarah_h
<hdv> sarah_h: one small thing… the accessibility consideration for copying the button isn't necessarily not an issue, because it would be in a different place in tab order which could be an issue
<hdv> sarah_h: I wonder if it would be worth looking at, if you want to put an image in front of text… and you want to do something like type to search, should it be part of that? is that going to break type to search… or should the author be able to define a separate string that gets used in those kinds of things?
<JonathanNeal> Brilliant, sarah_h. I totally forgot for a moment about the `value` attribute. Interesting idea, if you are suggesting we could somehow tag content as participating in the computed value.
<hdv> gregwhitworth: would encourage everyone to look at use cases around this… 
<JonathanNeal> Super loosely related. I remember Google did something a little bit similar to this with a `data-` attribute for marking things as participating in search.
<hdv> gregwhitworth: thanks everyone so much, watch Discord for next week's time, may be on a Wednesday
<gregwhitworth> Zakim, end meeting
<Zakim> As of this point the attendees have been dandclark, scotto_, hdv, JonathanNeal, masonf, bkardell_
<Zakim> RRSAgent, please draft minutes
<RRSAgent> I have made the request to generate https://www.w3.org/2022/09/29-openui-minutes.html Zakim
<Zakim> I am happy to have been of service, gregwhitworth; please remember to excuse RRSAgent. Goodbye

css-meeting-bot avatar Sep 29 '22 18:09 css-meeting-bot

I believe this is a very related feature request.

https://github.com/whatwg/html/issues/6507

And I have created a related proposal for this here:

https://github.com/openui/open-ui/issues/616

jonathantneal avatar Oct 04 '22 01:10 jonathantneal

I think it could be worth considering whether <option> elements need a prop to specify a string-only representation of the contents when selected, for a couple reasons:

  • type-to-select depends on a string comparison of the effective value, not the potentially complex content within an option
  • if/when we get an editable version of <selectmenu>, inputs do not support complex content, and I see benefit in having consistency across select-only vs. editable versions of selection components

smhigley avatar Oct 27 '22 18:10 smhigley

The Open UI Community Group just discussed [select] Should the inner HTML & styles of the selected option be copied into selected-value?.

The full IRC log of that discussion <gregwhitworth> Topic: [select] Should the inner HTML & styles of the selected option be copied into selected-value?
<gregwhitworth> github: https://github.com/openui/open-ui/issues/571
<jhey> pi would make the attribute shorter!
<bkardell_> also looking forward to the punny critical titles like how they are half baked or something
<hdv> gregwhitworth: to provide context: original issue was: we only put the text value into the selected-value part in, we don't also copy style.
<hdv> gregwhitworth: from that we pivoted to… what if you want not just style but also the DOM that was in the selected value, so like when there's a name + avatar + email, those get copied too
<hdv> gregwhitworth: so I went in and looked… almost all of them are never the complex content and 1:1 copied it. Even the Gmail/Outlook clients… they do something like I described, but then just show the value or part of it, not the whole thing
<masonf> q?
<masonf> q+
<hdv> gregwhitworth: I'm not seeing where folks would desire the full contents and place it into the selected-value
<scotto_> q+
<sarah_h> q+
<hdv> gregwhitworth: I think now we effectively take the innertext and put it in. So my proposed resolution would be to keep it as is… and to sarah_h's point from last time, folks can still copy the contents manually and do it manually
<gregwhitworth> ack masonf
<hdv> masonf: generally I think I agree with you, that most use cases don't seem to want this, and it does seem to complicate things
<hdv> masonf: so basically just use the innerText with no styling
<hdv> masonf: however… there's this thing called mateiral symbols, and probably things like it elsewhere… you use a text and the system will use an icon instead… that kind of use case would be broken by this behavior
<hdv> masonf: a potential solution that we haven't talked about a lot yet is imperative slotting
<hdv> masonf: that way you could keep everything
<hdv> masonf: limitation is that they have to be direct children of the selectmenu
<gregwhitworth> ack scotto_
<hdv> masonf: this may be an easy way to fix this?
<gregwhitworth> q+
<hdv> scotto_: it does seem that what people need here is guidance on using the <template> element and making up the markup they want to return
<hdv> scotto_: if we're going to allow nested interactives inside of options, we don't want those nested interactions inside of the value
<hdv> scotto_: it's always some variant of it, not the exact subtree
<gregwhitworth> ack sarah_h
<jhey> q+
<hdv> sarah_h: I put this in a comment in the issue, but to repeat that: I think there are two considerations: 'type to select' incl jumping to the matching option… having an editable selectmenu that is not datalist and actually works, having a prop to define a string representation of the option separately from its contents
<hdv> sarah_h: and that that would be displayed as an option
<hdv> sarah_h: like for structured styled content
<hdv> sarah_h: usually it is a subset or specific part of the content
<hdv> sarah_h: if we have an editable version of this, we probably want parity on how it works
<hdv> sarah_h: we might want to have things like 'cannot handle images', stuff like that.
<hdv> gregwhitworth: it makes complete sense, but also complicates things a bit
<hdv> gregwhitworth: the slot thing is an interesting thought but would not be in favour of it
<hdv> gregwhitworth: eg the author needing to adjust what is set in there if they have complex DOM structure
<hdv> gregwhitworth: the examples I've seen in email clients… like avatar+name+title of the person, if you grab innerText of that, it would grab title and name and then folks will need to clean that up
<hdv> gregwhitworth: do we actually want a feature where we allow that? if they're searching do we want a schema of what they're searching through?
<tantek> q?
<gregwhitworth> ack jhey
<gregwhitworth> ack gregwhitworth
<hdv> jhey: what would end user want to achieve with this? like I have a select menu and I just want to drop icons with each options… and when I select that I want to see the flag
<hdv> jhey: the paint point is styling the select, it's not just the selectbox, it's the whole thing, and we want to make it as easy as we can for people
<tantek> +1 jhey
<tantek> q?
<tantek> q+
<hdv> gregwhitworth: that case is pretty much why it was opened up… and in that case you could grab the DOM and clone the stuff in
<hdv> gregwhitworth: if that is the default behaviour, you end up with a lot of stuff by default and reach for script to find the things you want
<hdv> gregwhitworth: you could just hide it with DOM structures
<hdv> jhey: would there be some sort of slotted version of this?
<hdv> gregwhitworth: this is also kind of where sarah_h was going
<hdv> gregwhitworth: basically we're defining data binding… also done that in IDL space, but this is the first time this kind of issue has been defined
<hdv> gregwhitworth: this could be used for a lot of things
<masonf> q?
<masonf> q+
<JonathanNeal> q+
<hdv> jhey: you could do something in your options, an exclusion attribute where you could say just exclude the email from the option etc
<gregwhitworth> ack tantek
<hdv> tantek: either approach sarah_h was recommending is a good path to go down
<hdv> tantek: if we go down the route of cloning DOM, selected value could be a pseudo element that you could just style to show the pieces you want to show
<hdv> tantek: all the use cases mention a subset of the information from the richer display being displayed in the selected value display… it feels like that could all be done with CSS
<hdv> tantek: I appreciate the email example, but there are flags and other things we could do here
<hdv> gregwhitworth: it's a separate thing you can aready do
<hdv> d/aready/already
<hdv> s/aready/already
<gregwhitworth> ack masonf
<hdv> jhey: I thnk the most important thing is the developer experience of if you want your value shown, you don't want every developer having to write the boilerplate to do that, making that convenient would be the end goal here
<tantek> +1 jhey
<hdv> masonf: I just wanted to say… my concenr with making it cloneable… the easy example with flags is one thing, but if 99% of use cases do need JS to handle it because they are more complex, then I would want to avoid making the whole thing more complicated
<hdv> masonf: maybe this is more of a version 2 thing, as we learn how common this use case it
<hdv> s/it/is
<tantek> it sounds like most of these use-cases could be done with CSS, without JS. so I see the opposite, that 99% of the use cases won't need JS.
<gregwhitworth> q+
<sarah_h> +1 to what mason said
<gregwhitworth> ack JonathanNeal
<tantek> q?
<flackr> q+
<hdv> JonathanNeal: I think that this use case and the problems we're trying the solve, and some of the solutions, could be its own thing… 
<hdv> ack greg
<hdv> gregwhitworth: my issue is how to do it in a backwards compatible way
<hdv> gregwhitworth: so like jhey said most people would expect it to be there
<hdv> gregwhitworth: let's say a year from now we see that 60% of the scenarios, or 30 or 40… how can we still change it then?
<hdv> gregwhitworth: that's my concern
<sarah_h> q+
<hdv> masonf: it could be opt in
<hdv> gregwhitworth: ok I'm sold
<gregwhitworth> ack flackr
<tantek> curious what frameworks do for this, or rather, do any frameworks clone the DOM like we're proposing or do they all only provide "innertext"?
<hdv> flackr: I think you covered what I wanted to say, gregwhitworth, how do upgrade in a backwards compat way
<hdv> flackr: I think CSS is a natural way what it is from the option, it seems natural to change the appearance and hiding certain things just with CSS
<gregwhitworth> ack sarah_h
<hdv> sarah_h: this might be a terrible idea… it is common to clone a portion of an option rather than the entire thing… what about an idref association, where you say you selected-value-for and point to an ID that could be a child or self referencing, and then that element is cloned
<tantek> interesting, like a 'value-for' IDREF attribute
<hdv> scotto_: that's kind of what I was hinting at with the template element point
<hdv> gregwhitworth: could still be add on theoretically, like if it is not there we could still use innerText
<flackr> unless the default should be copy the innerHTML in the absence of value-for
<hdv> gregwhitworth: the proposed resolution I was going to put forward is we use it as is… I don't know now, I'm torn
<hdv> gregwhitworth: so let's not resolve on it today
<jhey> Icon fonts do worry me with using the innerText
<JonathanNeal> In that case, what happens to <optgroup>?
<hdv> gregwhitworth: feels like there are now 3 paths forward
<hdv> gregwhitworth: I will formulate the different paths forward
<hdv> gregwhitworth: thanks everyone!
<dandclark> Tricks with imperative slotting seem to have problems when the popup is open, when the option would need to be appear in two places simultaneously.
<gregwhitworth> Zakim, end meeting
<Zakim> As of this point the attendees have been flackr, JonathanNeal, hdv, scottkellum, masonf, scotto_, bkardell_, dandclark, una, chrishtr
<Zakim> RRSAgent, please draft minutes
<RRSAgent> I have made the request to generate https://www.w3.org/2022/10/27-openui-minutes.html Zakim
<Zakim> I am happy to have been of service, gregwhitworth; please remember to excuse RRSAgent. Goodbye

css-meeting-bot avatar Oct 27 '22 19:10 css-meeting-bot

After the discussion last week, we arrived at the following solutions:

  1. Clone innerHTML of the option and insert that into the selected value part and leverage CSS to hide what you don't want rendered
  2. Provide an implicit slotting functionality
  3. Provide an attribute that enables referencing what content you want cloned
  4. Keep as it's currently defined which is to take the inner text of the option and insert that into the selected value part

I'm personally in favor of 1 as the author will have the context of what they do and don't want to show and it's the easiest from a DX perspective. One of the examples raised was country select menus which have flag images inside of the option; you'd want this flag represented as well in the selected value. I shared a few other examples, such as email applications that showed an avatar, name and title but upon selection just the name was copied into the selected value.

gregwhitworth avatar Nov 01 '22 15:11 gregwhitworth

My thoughts on these options:

Cloning the innerHTML: Copying the HTML of the option seems like a reasonable choice. I would prefer a deep clone of the content over actually using innerHTML, since skipping the parser should be less complex and more performant. There are pitfalls here though:

  • Duplicate id references: if any script on the page refers to the contents of an option via ID, that will break.
  • Is the <option> itself included in the content that's copied, or only its children? If only the children are copied, then styles like option.redOption { background-color: red } will break. Devs will need to be careful to target styles to the children, and not the option elements themselves. But copying the option itself seems suspicious...then we'd have an <option> in a <button> which seems weird.
  • If the option or one of its children has a shadow root, should that be copied too? I think the answer is yes but not sure.

Implicit slotting: Using implicit slotting would require the slotted option to appear in two places at once when the <selectmenu>'s listbox is open. This is not supported by imperative slotting today, and I think it would add too much complexity. We can build on https://github.com/openui/open-ui/issues/616 to solve this long-term, but I don't want to have the initial version of <selectmenu> take a hard dependency on that.

Provide an attribute: I'm open to this. If we go this route we could probably punt the attribute to a future version and use a simple default like the current behavior of copying innerText only for <selectmenu> "V1".

Keep it as currently defined (inner text): This is my preferred choice if and only if the pitfalls listed with the Cloning innerHTML choice are too concerning/difficult to work around. We could keep this as the default and add an opt-in attribute later for more complex behavior.

dandclark avatar Nov 03 '22 16:11 dandclark

Forgive me for not following along better, but are these cloning options cloning things only within the lightdom, or are they cloning things from the lightdom into the shadowdom?

jonathantneal avatar Nov 03 '22 16:11 jonathantneal

By default, innerHTML and Node.cloneNode() will only get lightdom content, but we may want to define things for <selectmenu> so that shadowdom content gets copied as well.

dandclark avatar Nov 03 '22 16:11 dandclark

The Open UI Community Group just discussed [select] Should the inner HTML & styles of the selected option be copied into selected-value? #571.

The full IRC log of that discussion <hdv> Topic: [select] Should the inner HTML & styles of the selected option be copied into selected-value? #571
<hdv> github: https://github.com/openui/open-ui/issues/571
<hdv> masonf: this is about the ongoing discussion around what happens when you select an option in a selectmenu, what should be in the selected value in the button? currently it's the innertext but folks would like more of the content that the option has into the button once it is selected
<hdv> masonf: there are currently four suggesed solutions to this
<hdv> masonf: all listed in the issue https://github.com/openui/open-ui/issues/571
<jhey> q
<JonathanNeal> ack jhey
<flackr> q+
<hdv> jhey: other background on this… there was one use case that kept popping up (popovering up)
<hdv> jhey: it was about when you were using an icon font that turns words into an icon, it would be weird to see that text as the selected value
<hdv> masonf: yes, so currently the text content would go in there
<JonathanNeal> q
<JonathanNeal> ack flackr
<hdv> masonf: the four options currently presented are quite different directions
<masonf> q+
<hdv> flackr: my concern with treating this as a later option, if this is something that is common to do, it will have a more verbose syntax to opt in … so if we can find a way to do this now already I woould prefer that
<JonathanNeal> ack masonf
<hdv> flackr: I do think there is a fifth option… using the CSS image element function that paints an element in another location… this is not standardised though, so that may be tricky, but it would be interesting to use
<flackr> https://developer.mozilla.org/en-US/docs/Web/CSS/element
<jhey> q+
<hdv> masonf: I think the general consensus is in most real use cases of a selectmenu, when there is content in an option, it is actually different from what you would want to display in the button. Maybe it is rich context, but it is not the exact same rich content
<scotto_> q+
<hdv> flackr: maybe you could do that with a pseudo class though
<JonathanNeal> ack jhey
<hdv> masonf: yess depending on how you would do it, eg couldn't do that with the image function
<hdv> jhey: I wonder if you could do it with selected bits… like with flags, people might say I just want to see the icon, but I don't want to write a script because I would end up writing scripts over and over again
<JonathanNeal> q
<masonf> q+
<hdv> jhey: echoing flackr, I would also prefer if we could do it now rather than later
<JonathanNeal> q+
<JonathanNeal> ack scotto_
<jhey> q+
<hdv> scotto_: one of the things that wasn't brought up before… display:none could be used on elements that you wouldn't want to show… however in most situations that we're talking about, when using CSS to hide things or do behaviors, that would otherwise be done by the User Agent, how would this be done in situations like Reader Mode?
<hdv> scotto_: how would we make sure that hat sort of stuff wasn't ;displayed in those cases?
<flackr> qq+
<hdv> scotto_: CSS is a strong suggestion, not a requirement
<hdv> flackr: does selectmenu require that you also use their CSS, because then not only the current item would be broken but everything else?
<JonathanNeal> Good point, scotto_, about having access to the content itself, versus (purely) the visual painting of it.
<hdv> scotto_: well the UA would provide a default for selectmenu
<hdv> scotto_: one of the main issues with allowing authors to do this is that we have no control over what they do
<JonathanNeal> q
<JonathanNeal> ack flackr scotto_ masonf
<JonathanNeal> q
<JonathanNeal> ack flackr
<Zakim> flackr, you wanted to react to scotto_
<hdv> masonf: one of the things people seem to want is to allow developers to decide what to display… seems to preclude any kind of image() magic
<JonathanNeal> ack scotto_
<JonathanNeal> ack masonf
<hdv> masonf: would it be worth spending some more time on those solutions or are there other solutions we haven't thought about yet?
<JonathanNeal> ack JonathanNeal
<JonathanNeal> ack jhey
<hdv> jhey: I'm not too familiar with things like reader more… it seems a bit like things like Print CSS
<hdv> jhey: I'm trying to think of how it is done in other places, like some people use a hidden attribute in some places?
<flackr> font selector needs font with its font family applied
<hdv> jhey: what about some attribute that is like the opposite of hidden and that clones it across
<hdv> masonf: one of the things I've heard folks want is when they use a font that it copies that across as well
<hdv> jhey: like selecting a font style in a dropdown?
<JonathanNeal> q+
<bkardell_> many selects can be expanded another way - think about a tax form that has 10 choices displayed as a select because that's just nicer management of visual space and interactions, but they could be radio buttons or checkboxes - which was pointed out to me when I posted my affordances piece
<bkardell_> (for print, for example)
<hdv> masonf: when your options have different font styles, for those styles to show up in the selected option you would need to do something extras
<hdv> s/extras/extra
<hdv> ack jon
<hdv> JonathanNeal: I'm used to elements absorbing all of their contents …something like a reader mode can interpret that to change its display… but it is always working with a node tree, never just, say, a picture of it
<hdv> JonathanNeal: would there be a compelling reason to do it differently, or are there more cases where the HTML changes by context to be optin instead of optout?
<jhey> Ahh bkardell. This is an ancient Hulk canvas I have that's a comic cover. It says "July 105" on it but I couldn't confirm the validity of that ha.
<hdv> JonathanNeal: how I would expect it to work just like a div, it's the HTML I wrote… if I want to style that element by its state, maybe I would have a pseudo to style
<hdv> masonf: if we go the cloning HTML route is the style of that… your styles apply in a particular way, if we clone that to a different spot in the DOM, it isn't going to styled in the same way
<jhey> I Googled it. It's a canvas of the July 105 edition of the incredible hulk :D
<hdv> scotto_: that's true, even in this context it is not even an option anymore
<hdv> scotto_: you would have to carry over the class as well, reapply it to an element… there could be breaking changes to the way the button looked
<hdv> masonf: and it would go in the shadow root too
<hdv> flackr: isn't the different styling intentional though?
<hdv> JonathanNeal: in a font picker… if we have a list of all 12 fonts we have, each font name is in its font family, in that case as a developer I might style each of those in the light dom, I would expect them being slotted in
<hdv> JonathanNeal: although the expectation is it would more into the shadow dom, I am styling the element as if I authored it
<hdv> JonathanNeal: would it make sense to keep the styles eventhough I'm cloning it
<hdv> masonf: not sure how that would work technically
<hdv> masonf: if you take it and move it somewhere, it is inside the shadow root somewhere, so most styles don't apply anymore… so then we would need to do additional magic to do inline styles or something like that
<hdv> JonathanNeal: if deeper slotting were possible, would this not have been an issue, because it would have effectively been slotted like child content would normally be?
<jhey> q+
<hdv> JonathanNeal: like in the font drop down, we click the select and see all of our options… if those weren't actually cloned but just slotted, they are still their original light DOM element… thinking how shadow DOM typically works, what issues would we have that make it different from that?
<bkardell_> what we need here is WormholeDOM
<hdv> masonf: that's how selectmenu currently works
<hdv> masonf: the issue happens when you take one of the options and slot i
<hdv> s/i/it
<flackr> q+
<hdv> masonf: I think the route you're going down is the second option we talked about
<hdv> masonf: where the option would no longer be slotted in the option but it would be slotted in the button… because it can only be in one place
<JonathanNeal> ack jhey
<scotto_> q+
<hdv> jhey: if people will style their options, I don't think people would mind too much if they had to style it one more time when it ended up in the option
<JonathanNeal> ack flackr
<hdv> jhey: I think last week we talked about email + name + avatar in the option and then the button would contain only some of them, not all
<masonf> q+
<jhey> +1
<hdv> flackr: I think the imperative slotting… if we can't show two copies of the thing, it's probably not going to work, because typically you expect to see it in the selected slot as well as in the list
<tantek> +1 flackr
<JonathanNeal> +1 to expecting it to be a clone, including any rich content.
<hdv> flackr: one way it could work if we cloned it in a slot that existed in the same level as the item slots
<hdv> masonf: so the developer would need to stick another bit of markup in for a placeholder?
<hdv> flackr: no would be something selectmenu deos
<hdv> s/deos/does
<hdv> masonf: so you're saying clone it into the light DOM as a child of the selectmenu
<hdv> flackr: yes
<JonathanNeal> ack dbaron
<JonathanNeal> +1 to that dbaron, that I would see both during the dropdown
<hdv> dbaron: responding to what masonf suggested about removing from the list of options. You would expect the selected thing both in the listbox and in the button, it could be confusing
<masonf> q?
<JonathanNeal> ack scotto_
<hdv> s/confusing/confusing to not see both available
<sarah_h> q+
<hdv> scotto_: as we discussed last time… it's not necessarily a 1:1 match between what people want and what the default… why don't we allow folks to set up what they want in a template, then they could even decide what the order is without having to mess around in CSS for that
<flackr> q+
<hdv> scotto_: it seems that a template would actually give more control over things
<JonathanNeal> ack masonf
<hdv> masonf: that's kind of a third way to do this as well… interesting…
<JonathanNeal> I am wondering if it could be a clone of the element that inherits the styles of the original, but target-able with a pseudo-element on the original selector.
<hdv> masonf: there are a lot of tricky issues to be solved with this capability… when you combine that with the fact that most selectmenus don't clone one and not the other, then perhaps it is good to do this in a v2… we will learn a lot in the first phase when people starting to use it
<hdv> masonf: I am afraid this could be a technical lift with a lot of problems that don't exist on the web yet
<JonathanNeal> ack sarah_h
<jhey> We can definitely get it over 20 characters Mason. selectmenuexcludedoptionchild
<hdv> sarah_h: wanted to +1 what scotto_ says and what masonf said before… I would prefer a separate way to define markup for the selected option… rewriting styles introduces a lot of problems with tools developers use like generated classnames
<JonathanNeal> selectmenu .my-option { /* default styles */ } selectmenu .my-option::reflection { /* override styles */ }
<hdv> sarah_h: that would be a major thing to work around
<hdv> sarah_h: being able to define a separate template would be ideal I think
<hdv> sarah_h: we also need a way to define a string value for options but that's a different discussion
<JonathanNeal> ack flackr
<hdv> flackr: Sarah, are you saying that if the same selectors match but you had a pseudo class, that would not work with tooling?
<JonathanNeal> Or selectmenu .my-option { /* default styles */ } selectmenu .my-option::selected-option { /* override styles */ }
<hdv> sarah_h: not with ours at the moment, we generate classnames based on what styles are used, like a classname called opacity
<hdv> flackr: how do you do hover?
<hdv> sarah_h: also with a classname
<JonathanNeal> q?
<JonathanNeal> Re: light dom cloning. I would not want selecting an option or opening a menu to trigger a mutation.
<hdv> flackr: I also wanted to respond to the templating idea; it leads to a lot of duplication of content, so like in the flag selector, or email+avatar selector, you probably want almost the same in the selected option and then would need to write that again
<hdv> scotto_: fair point
<hdv> JonathanNeal: do we feel like we have something actionable here? seems to me more research is needed as the different possibilities come with their own complexities
<masonf> thanks tantek
<hdv> JonathanNeal: because each of them would have different consequences, is there anything beyond narrowing down more and research more?
<hdv> masonf: one question… is this a critical feature and is selectmenu broken without it? how does the group feel about it?
<jhey> q+
<hdv> scotto_: I don't think it is a blocking issue personally
<hdv> masonf: all of this is all 100% doable with some lines of JavaScript, this discussion is just about trying to make it work so that authors can do it without JavaScript
<flackr> q+
<JonathanNeal> ack jhey
<tantek> +1 to scope to declarative
<hdv> jhey: if the feature isn't there at the start and a lot of people expect it… not sure what the impact is
<hdv> jhey: yes it is a few lines of JavaScript, but a lot of folks using this may be using a library to do it… and they abstract it from that button codes but with props… the behaviour would be kind of similar for framework users if we had a way to do this
<hdv> jhey: people could write wrappers for it of course
<scottkellum> +q
<JonathanNeal> ack flackr
<hdv> flackr: there are cases wheree just showing the plain text will be broken as welll, like an avatar selector will have just images, so you would just see nothing
<JonathanNeal> ack scottkellum
<JonathanNeal> +1 to this being an important feature in declarative
<hdv> masonf: it seems like folks think this is a pretty important feature, so seems like we should keep talking about it in the issue
<hdv> masonf: would be super helpful if folks can help think about how things would work in, like, DOM terms
<JonathanNeal> I like this game, “Where did my DOM go?”
<JonathanNeal> Nit on avatar selector: it will still need some text description, tho, yea?
<hdv> scottkellum: it will be really interesting to roll this out and see what people are doing in terms of layering on with JavaScript frameworks
<JonathanNeal> q?
<hdv> scottkellum: I like this sort of phased approach a lot: putting it out to see what people do and then expand and improve in the future
<scotto_> +1
<hdv> JonathanNeal: would say text is like a minimum viable thing you could put in there
<hdv> masonf: if we don't go the route of having styled option… I think there would be an issue to discuss of what to do when there is no text
<hdv> JonathanNeal: unfortunately we can't go into the next issue, we'll talk about that one next week
<scotto_> not if someone made their options like <option><img src=...></option>
<scotto_> but you'll notice my example didn't have an alt
<hdv> no one would possibly do that
<hdv> oh wait
<hdv> JonathanNeal: for housekeeping… it was brought up Zoom might not be the best place to have meetings, would someone like to spin up a GH issue to discuss alternatives?
<hdv> flackr: I can start an issue
<hdv> Zakim, end meeting
<Zakim> As of this point the attendees have been tantek, flackr, stephstimac, dbaron, scottkellum, bkardell_, scotto_, hdv, JonathanNeal, dandclark, masonf, jhey, sarah_h
<Zakim> RRSAgent, please draft minutes
<RRSAgent> I have made the request to generate https://www.w3.org/2022/11/03-openui-minutes.html Zakim
<Zakim> I am happy to have been of service, hdv; please remember to excuse RRSAgent. Goodbye
<JonathanNeal> hdv: the real hero

css-meeting-bot avatar Nov 03 '22 18:11 css-meeting-bot

I believe it should contain everything the option has inside of it. If the developer does not want to show the image or other SVG inside of the selected-value, this could be easily achieved by targeting and hiding it with CSS. This at least would be easier than the other way around.

What I do wonder about is the use of id's inside of the option html... but the question about this becomes about what do people want most: automatically clone images, or not use id's inside of option html. It's a hard one.

Maybe it could be an attribute on the select menu? Something like allow="text" and default set it to all? Or maybe that is a bridge too far? Very interesting topic.

The demo where I wanted to use it can be found here (had to fix it with JS, disable JS to see result without it): https://codepen.io/utilitybend/pen/zYLoqge

brechtDR avatar Jan 12 '23 14:01 brechtDR

I believe that we should keep selectmenu as is and not copy/clone/slot anything from the selected option into the selected value slot. Copying innerHTML seems error prone and could lead to funny results especially if we are always doing it by default.

Copying innerHTML and styles could be recreated quite easily if that's what the author wants to do with a little bit of script: https://jsfiddle.net/jarhar/83gpscra/

selectmenu.addEventListener('change', () => {
  selectedvalue.innerHTML = selectmenu.selectedOption.innerHTML;
  selectedvalue.className = selectmenu.selectedOption.className;
});

We could try slotting the selected option into the selected value when the listbox is closed, but I don't think that having the selected value change when the listbox is opened vs closed is great. Using a mirroring primitive to do this would be ideal, but implementing and shipping something like that is a lot harder than the selectmenu element itself. If mirroring is ever implemented in the future, then we could provide an opt-in upgrade path to use it in selectmenu.

https://github.com/openui/open-ui/issues/435 also brought up the idea of being able to automatically apply something selectable in CSS to both the selected option and selected value, such as an attribute. I still think that doing this with script as I did in my example above is good enough and will make selectmenu easier to ship.

josepharhar avatar Mar 10 '23 16:03 josepharhar

While I mostly agree when it comes to safety of this, there is a downside by doing this with JS. Just a few pointers that come to mind here:

The original state should also be taken into account. As the default selected option might change on page load (quick example that comes to mind: server selection for a game, when server is full on a new page load, another item should be default selected and previous option disabled).

If we were to switch the initial innerHTML on page load, chances are high, there is a visual delay caused by this initial switch. I already seem to have this issue by just using 2 svgs.

Another thing to take into account, as it stands at the moment, the change event won't cause the selectmenu to update when using keyboard(arrow) navigation to toggle between the options. But this might be something else that can be handled later on.

brechtDR avatar Mar 13 '23 08:03 brechtDR

How about an attribute which can be toggled to change the behaviour ? Something like:

inheritInnerHTMLAndCSSFromSelectedOption=true

Defaults to false for safety ?

clarumedia avatar Mar 13 '23 08:03 clarumedia

as it stands at the moment, the change event won't cause the selectmenu to update when using keyboard(arrow) navigation to toggle between the options

If you're talking about changing the selected value while the listbox is closed, we have decided to not support this: https://github.com/openui/open-ui/issues/433

If you're talking about using arrow keys to focus to next/previous options in the listbox, we shouldn't be changing the actual selected value until the user presses enter, right?

If you want to change the selected value before the user actually commits to the option by pressing enter and causing a change event to be fired, I think that's not a good idea

If we were to switch the initial innerHTML on page load, chances are high, there is a visual delay caused by this initial switch. I already seem to have this issue by just using 2 svgs.

If you can't run script before the first render, then yeah I guess you'd have to make the initial HTML include the correct HTML for the selected option. It would take more work but it isn't impossible.

How about an attribute which can be toggled to change the behaviour

Having an opt in like this does sound a lot better than doing it by default, but I'm worried that this isn't a good enough solution to make it past a whatwg/HTML review - namely that copying innerHTML in general might not be a good idea to allow at all, and that I don't think any other HTML elements have attributes to opt into behavior like this.

josepharhar avatar Mar 14 '23 00:03 josepharhar

I think it's an interesting one to further discuss in a meeting. I'm really wondering what other people think about this. As there are so many use-cases where images/svg can be handy to be handled automatically and would remove the use of extra JS.

  • country selection (flags)
  • type of profile selections (for roles such as admin, editor. including symbols such as a pen or settings icon)
  • Category selections (for example sports website: tennis racket, golfclub, football, etc..)

Wether it is with an extra attribute or not, really isn't my biggest concern to be honest. It's more about having the ability in general without relying on JS. People use a lot of libraries for these things already.

I understand accessibility concerns, or creation of multiple id's in the document, but should this be our concern or the developers concern when creating something? (Speaking as a full-time front-ender myself).

brechtDR avatar Mar 14 '23 08:03 brechtDR

The Open UI Community Group just discussed [select] Should the inner HTML & styles of the selected option be copied into selected-value?, and agreed to the following:

  • RESOLVED: Don't implement behavior to copy innerHTML from the selected option into the selected value for V1 of selectmenu
The full IRC log of that discussion <gregwhitworth> Topic: [select] Should the inner HTML & styles of the selected option be copied into selected-value?
<gregwhitworth> github: https://github.com/openui/open-ui/issues/571
<tantek> regrets+
<hdv> jarhar: there is a request to have some way of mirroring the selected option, the contents of it, into the 'selected-value'
<hdv> jarhar: it makes sense, but there isn't a great way to do it
<masonf> q+
<hdv> jarhar: using something like a mirror primitive to do it would be really cool but doesn't exist yet. Another way would be to copy innerHTML in to the selected value, but it seems kind of error prone, eg if you have an ID in there and it gets copied that could get you into trouble
<hdv> jarhar: don't think it's a great idea, but if you want to do it you could do it in a few lines of script
<hdv> jarhar: (see my comment in the issue)
<hdv> jarhar: I don't think we should do this automatically… but there was the suggestion to have an attribute or something to allow folks to opt in to a behaviour like this. I would lean towards not doing this
<gregwhitworth> ack masonf
<flackr> q+
<hdv> masonf: +1… for a couple of reasons we should at least wait. This is the kind of thing that could be added in a later stage. The copy/paste innerHTML has issues, like the ID issue jarhar mentioned, but also where do you copy it… and it's even harder when shadowroots come into play
<masonf> q?
<gregwhitworth> ack flackr
<scotto> +1. we've gone over this a few times already re: accessibility issues with copying in non-static HTML elements into the triggering element
<hdv> flackr: I wanted to +1 as well… I do like the idea of exploring making this work but it makes sense can't do it now
<hdv> JakeArchibald: I'm new… where does this live is there a spec?
<hdv> masonf: there is a plan to do a PR to WHATWG for this
<hdv> JakeArchibald: for this agenda item I missed a summary of the item
<bkardell_> "the story so far"
<hdv> JakeArchibald: eg in the CSSWG if I bring something there I would add a summary as the last comment to the issue, to make it easier to get “the story so far”
<hdv> masonf: we do kind of do that, sometimes, good suggestion, we could do better
<masonf> https://github.com/openui/open-ui/issues/571#issuecomment-1464068312
<hdv> gregwhitworth: good callout! it could be useful also to do verbally
<hdv> gregwhitworth: for this issue: this is about when in a selectmenu you have an option that has more than just text in the options, like a country selector with flags, would it need to be possible to see the same thing as the selected value
<hdv> gregwhitworth: I'm hearing: let's keep it as we resolved.
<hdv> masonf: I think part of the resolution would be… we don't necessarily disagree with this functionality, but mostly feel it would need to move to some next iteration
<jarhar> Proposed resolution: Don't implement behavior to copy innerHTML from the selected option into the selected value
<jarhar> Proposed resolution: Don't implement behavior to copy innerHTML from the selected option into the selected value for V1 of selectmenu
<masonf> +1
<dandclark> +1
<scotto> +1
<hdv> +1
<jarhar> RESOLVED: Don't implement behavior to copy innerHTML from the selected option into the selected value for V1 of selectmenu

css-meeting-bot avatar Mar 16 '23 15:03 css-meeting-bot

I talked to @mfreed7 and @domenic about what our options are to solve this, and this is what we came up with.

TL;DR I think that we should have the browser cloneNode() the contents of the selected <option> into the <selectlist>'s <selectedoption> element, replacing the child nodes of the <selectedoption> element. If someone along the way to getting this standardized comes up with a more elegant solution, I'm happy to switch to it. I am currently implementing a prototype of this in chromium.

Cloning selected <option>’s children into a ShadowRoot of <selectedoption>

<selectedoption> would have a user-agent ShadowRoot, and every time that the selected <option> changes, we would remove all children of the <selectedoption>’s ShadowRoot, cloneNode the <option> and append each child of the clone to the <selectedoption>’s ShadowRoot.

We would also need to provide a pseudo-element, like ::selectedoption(), so that CSS can make distinctions between the <selectedoption> and <option> content and also target the content inside the <selectedoption>’s ShadowRoot.

This is similar to how svg use works.

Issues:

  • We can’t do this and prevent script from accessing the user-agent shadowroot of the <selectedoption> or the <selectlist>.
  • document.querySelector(::selectedoption) would give script access to nodes inside of the user-agent shadowroot. From there they can traverse up the tree.
  • What if you clone a <script> element? (You could use currentScript to access an inside-the-tree node.) We could try to avoid cloning scripts, but what about iframes? (they could use frameElement).
  • We may need to resolve https://github.com/whatwg/dom/issues/808 in order to make sure cloned elements don’t execute script synchronously during the clone/append.

Cloning selected <option>’s children into the light DOM of <selectedoption>

This is the same as the cloning into ShadowRoot option, but instead of having a ShadowRoot to clone into, we would just replace the <selectedoption>’s regular DOM children with the cloned nodes.

Issues:

  • Nothing in HTML currently modifies light DOM like this. The spec could make it an authoring conformance error to set any child nodes of <selectedoption> though.
  • We may need to resolve https://github.com/whatwg/dom/issues/808 in order to make sure cloned elements don’t execute script synchronously during the clone/append.

Support element() in CSS to mirror the content internally

Firefox implements this as a way to mirror content in CSS: https://developer.mozilla.org/en-US/docs/Web/CSS/element We could implement this and then use it internally to mirror the rendered output of the selected <option> into the <selectedoption>.

Issues:

  • Doesn’t provide a way to style the <selectedoption> separately from the <option>.
  • Typically the box size of the options displayed in the listbox is different from the in-page box size of the <selectlist> element. So the mirrored image would need to be cropped or stretched to fit.
  • Doesn’t provide actual DOM in the <selectedoption>, so no systems would actually know what’s inside the <selectedoption>. Screen readers can’t read this, or at least would need to be modified in order to deal with it. What if you want to support selection?
  • Chromium and WebKit don't have implementations of this, so it would take more engineering effort to get done in those browsers

Magical mirroring

We could try to find a way to have the children of the selected <option> also appear in the flat tree or layout tree of <selectedoption>.

A similar idea was proposed here, although I’m not sure this would actually be the same thing: https://github.com/whatwg/html/issues/6507

Issues:

  • This may be difficult or impossible to implement
  • It is an invariant that nodes/objects only appear once in a dom tree, flat tree, or layout tree
  • "The same node" appears as a child of both <selectedoption> and <option>. How does this work with CSS selectors? E.g. selectedoption > .foo { ... } and option > .foo { ... } are supposed to give different behaviors to accomplish the differential styling goal, but they are targeting "the same node", because CSS selectors select nodes, not flat tree/layout tree objects.

Give up and make everyone add script

This is the script that would be required for web developers to implement the “cloning into light DOM” idea:

selectlist.addEventListener('change', () => {
  while (selectedoption.firstChild) {
    selectedoption.firstChild.remove();
  }
  for (const newChild of selectmenu.selectedOption.cloneNode(true)) {
    selectedoption.appendChild(newChild);
  }
  selectedoption.className = selectmenu.selectedOption.className;
});

Issues:

  • Allegedly, 80% of selectlist use cases would want this behavior, and if they all have to copy & paste this script everywhere and make it work, it kind of erodes the value of having selectlist in the first place. Declarative solutions are important, and authors may choose to not use this element if we don’t offer one.

josepharhar avatar Aug 29 '23 01:08 josepharhar

Thanks for the great summary Joey. I'll reiterate my perspective that, although this sort of light-DOM modification is strange and unprecedented, it seems to me to be the only reasonable option for accomplishing the use case.

I also want to note that this new technique, of elements that modify their own light DOM, might be necessary to solve a few other long-standing HTML feature requests. Namely:

  • Client-side includes (https://github.com/whatwg/html/issues/2791): what people generally want here, is something like <include src="foo.html"></include>, where the contents of foo.html end up inside the light DOM of the <include> element.

  • Various "format my contents" element proposals, e.g. https://github.com/whatwg/html/issues/9294 or https://github.com/whatwg/html/issues/2404. Authors want something like <relativetime>2023-08-28T00:00:00Z</relativetime> or maybe <relativetime value="2023-08-28T00:00:00Z"></relativetime> to "display as" 2 days ago. How would you do that? As noted in https://github.com/whatwg/html/issues/2404#issuecomment-1670907485 it's rare for the user agent to introduce new display text separate from the light DOM. If we just had those elements update their own light DOM, maybe it would work.

I'm not saying that we should necessarily tackle either of these two feature requests, or that the best way to do them is with light DOM modification. But I wanted to provide some evidence that the platform has been straining against this constraint of "light DOM is entirely for author territory, and should not be modified by UA script" for a while, and that if we consciously cross that boundary, in a well-designed way, it might open up new options going forward.

domenic avatar Aug 29 '23 04:08 domenic

There hasn't been any discussion on this issue for a while, so we're marking it as stale. If you choose to kick off the discussion again, we'll remove the 'stale' label.

github-actions[bot] avatar Feb 26 '24 00:02 github-actions[bot]

The plan is still to use clonenode to copy the contents of the selected <option> into <selectedoption>

josepharhar avatar Mar 21 '24 18:03 josepharhar

The Open UI Community Group just discussed [select] Should the inner HTML & styles of the selected option be copied into selected-value?, and agreed to the following:

  • RESOLVED: we already resolved to clone content from options into `<selectedoption>`. We will stick with that resolution.
The full IRC log of that discussion <brecht_dr> gregwhitworth I think we already resolved on this?
<brecht_dr> jarhar I think we can just close this
<brecht_dr> Luke agree
<brecht_dr> masonf the last comment is actually supportive of the latest plan we have, so we can move forward with it
<brecht_dr> gregwhitworth does anyone agree with just closing this issue?
<brecht_dr> keithamus Might be nice to add some messaging to it
<masonf> Proposed resolution: cloning content from options into `<selectedoption>` still seems like the best way forward.
<brecht_dr> masonf we want the rich content in the selectedoption right?
<masonf> Proposed resolution: we already resolved to clone content from options into `<selectedoption>`. We will stick with that resolution.
<brecht_dr> +1
<masonf> +1
<Luke> +1
<una> +1
<masonf> RESOLVED: we already resolved to clone content from options into `<selectedoption>`. We will stick with that resolution.
<gregwhitworth> Zakim, end meeting

css-meeting-bot avatar Apr 25 '24 19:04 css-meeting-bot