-
Notifications
You must be signed in to change notification settings - Fork 686
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
"Single content, multiple renderings" feature for <selectlist>
#9284
Comments
The CSS Working Group just discussed The full IRC log of that discussion<fantasai> Topic: Select List<astearns> github: https://github.com//issues/9284 <fantasai> jarhar: Joey from Google <fantasai> jarhar: in Open UI we've been working on new HTML element called <selectlist>, intended to be more customizable select <fantasai> jarhar: ran into issue of wanting render one piece of user markup in two different places at the same time <fantasai> jarhar: and make them independently styleable <past> Selectlist element explainer for more context: https://open-ui.org/components/selectlist/ <fantasai> jarhar: this is an example of a select list, one of the common desires is adding icons for each item <fantasai> jarhar: so you can use an option, and see the button <fantasai> jarhar: entire contents of option, not just text <fantasai> jarhar: do this with <selectedoption/> <fantasai> jarhar: currently implemented via cloneNode() <fantasai> jarhar: replace content with selected option <fantasai> jarhar: chose this solution because not much better option <fantasai> jarhar: considered shadow DOM, but hard to style <fantasai> jarhar: considered requiring authors to add script, but want declarative <fantasai> jarhar: several others <fantasai> jarhar: I mentioned styling differently, here's another example <fantasai> jarhar: button renders content differently from options in the list box <fantasai> jarhar: shows symbol, not the text <fantasai> jarhar: accomplished with CSS rule that sets text to 'display: none' but only when inside selectoption element <fantasai> jarhar: wanted to ask if CSS has a better way to do this <fantasai> jarhar: cloning the user DOM into another part of HTML spec is unusual, there's no precedent <fantasai> jarhar: concerned might be error-prone <fantasai> annevk: also creates synchronization issues <fantasai> annevk: HTML elements are expected to be ??? <astearns> s/???/live/ <fantasai> annevk: you'd have to clone, and gets very messy very quickly <TabAtkins> s/???/live/ <fantasai> annevk: wanted to have two sets of render ??? <TabAtkins> q+ <fantasai> TabAtkins: only one spot in the DOM, but render twice <fantasai> jarhar: idk what part of rendering or which tree this might exist in <past> s/???/boxes/ <fantasai> jarhar: [something about Shadow DOM] <bkardell_> q+ <fantasai> jarhar: Here's the problem, if anyone wnats to comment in the CSSWG issue we opened, that would be helpful <TabAtkins> ack TabAtkins <astearns> ack TabAtkins <astearns> ack bkardell_ <fantasai> bkardell_: Similar thing [fades out] <masonf> cna't hear brian <masonf> s/cna't/can't <astearns> s/[fades out]/have been requested <fantasai> bkardell_: this has been asked for in several ways at different times <masonf> jarhar can you stop presenting so we can see people? <fantasai> bkardell_: e.g. elements() in CSS <fantasai> bkardell_: issue on Open UI 616, cgives use cases and rationale <fantasai> bkardell_: March 2021 HTML 6607 asking for an element like <slot> but called <mirror> for similar needs <fantasai> bkardell_: clear desire for something like this <fantasai> astearns: then let's leave this as Yes, we want to do this <fantasai> astearns: ask CSSWG to review |
Is this possibly similar to fragmentation? That seems another case where one element has multiple layouts but rather than continuing from the previous breakpoint we would restart from the beginning. |
Just wanted to note that there is a precedent for multiple rendering of an identical element in SVG, but the styles are not fully open, only a few things (color, size, etc...) were customizable. https://developer.mozilla.org/en-US/docs/Web/SVG/Element/use Despite that precedent, I think a full redo-css style rule matching on a virtual element is going to be difficult for UAs to implement. If the goal is to allow full customizability, cloning the HTML is more likley to be a good solution. |
So I think that, in general, "one content, multiple renderings" is acceptable mechanically. Whatever layout-tree abstraction a browser uses can, at least in theory, handle a many-to-one relationship with the dom tree. The main issue is that some relevant state for rendering might be stashed on the element rather than the layout node, but that's presumably fixable. (And as flackr points out, fragmentation already, to some extent, exposes these issues.) The big question is about targeting your styling, tho. The current "just clone it" behavior makes this easy - any styles you write to target the option sub-elements will target the copy as well, so long as you're not too specific with context in the selector. So, how do we target the stuff when it's not cloned? I think there are two options:
Do we want to support being able to style differently based on which node was selected? That is, if the first option is selected it's styled as X, but if the second option is selected it's styled as Y. I presume this is necessary, since the options can have different markup. In that case, we would need to have a way to go from option -> selectedoption. In my (1) above that's easy if we make the In (2) we'd need to do something else; maybe we'd allow the direct "pretend to be descendants of |
That said, you can go pretty far these days with custom properties. A <option>
<img alt="" />
<span>Belgium</span>
<option>
<selectedoption /> .country-select > option > span {
color: var(--selected-color, currentColor);
font-style: var(--selected-font-style, normal);
}
.country-select > selected-option {
--selected-color: gray;
--selected-font-style: italic
} and for the case where you want to hide the text, you would have a The styles you set on |
In both of these cases, what happens when you do
Sorry, can you help me understand this proposal? |
How would event handling work in this case? Would event.target be option element for both renderings? What if pointer moves directly from one rendering to another, is one supposed to get out/over/leave/enter events? What would getBoundingClientRect() return in multiple renderings case? |
IMO this gets pretty complex very quickly. The closest thing we have in engines today is repeated headers/footers for tables when printing - but this has lots of complexities - and has the same DOM content. E.g. some implementations just repeat the painting commands at a different offset - e.g. they don't support arbitrary different content. Lots of (complex!) questions would need to be answered (as @smaug---- notes), e.g. what happens during hit-testing, selection() type APIs (which operate off the DOM) etc. TL;DR avoid if possible. |
Closing this in favor of #10242 |
Please see this comment in OpenUI for more of the background for this question. But the TL;DR is that for the
<selectlist>
element, there's a need for the currently-selected option to be rendered in two different places: once in the popover listbox, and once in the page. And there's further a need to be able to style these differently. Commonly, the listbox contains a different presentation of the same content - for example, more details in the listbox, and a smaller summary in the in-page control once selected.The OpenUI comment goes through several different ways to achieve this "single content, multiple renderings" feature for
<selectlist>
. The top contender is just to callcloneNode()
on the content from the<option>
, to copy it into the in-page control, so there really are two concrete copies of that content, which can then be styled with normal CSS. That approach meets the use case very nicely, and is implementable, but would be a new "thing" for the platform. However, one other suggestion (which falls under the "Magic Mirroring" heading) is to have some way for the DOM content to live in only one location, but get rendered in two places, with different styling applied to each place. This CSSWG issue asks the question: is there a way to do that?One suggestion (not listed in the comment) is to give the
<selectlist>
two pseudo classes, which can be used to match the "two faces" of that content:From a developer point of view, this meets the use case - I get two "magic" copies of
<span class=foo>
and I can address each of them via CSS to style them differently. What it leaves out is the "how". I'm not sure how we would spec or implement such a behavior. But I thought I'd open an issue here to discuss the general problem and this particular idea to see if it has legs.The text was updated successfully, but these errors were encountered: