csswg-drafts
csswg-drafts copied to clipboard
[css-ui] DOM/Box structure for appearance:base-select
Now that we have decided in https://github.com/w3c/csswg-drafts/issues/5998 to use CSS to opt into the stylable/interoperable mode for <select>, we should figure out what the DOM/box structure should be.
In the OpenUI design and chromium implementation, there is a closed UA shadowroot on <select> which gets rendered when appearance:base-select is set:
<select>
#shadow-root
<!-- There are additional proprietary elements here which are only
used for appearance:auto/none mode. They aren't included in the
layout tree when appearance:base-select is set, and likewise,
the below elements aren't included in the layout tree in
appearance:auto/none mode. -->
<slot id="select-button">
<button pseudo="select-fallback-button">
<span pseudo="select-fallback-button-text"></span>
<div pseudo="select-fallback-button-icon">
<svg viewBox="0 0 20 16" fill="none"><path d="M4 6 L10 12 L 16 6"></path></svg>
</div>
</button>
</slot>
<slot id="select-datalist">
<datalist pseudo="select-fallback-datalist">
<slot id="select-datalist-options"></slot>
</datalist>
</slot>
</select>
Here is a mapping of which children of <select> will be slotted into the <slot>s in the structure above:
<slot id="select-button">: The first<button>child of<select>. This represents the in-page button which opens the popup containing options. If the author doesn't provide a button, then<button pseudo="select-fallback-button">gets rendered instead. Here is an example of author HTML which would use this slot:<select> <button>i am slotted into id=select-button!</button> </select><slot id="select-datalist">: The first<datalist>child of<select>. This represents the popup containing options, which is implemented as a popover anchored to the button. If the author doesn't provide a datalist, then<datalist pseudo="select-fallback-datalist">is rendered instead. Here is an example of author HTML which would use this slot:<select> <datalist>i am slotted into id=select-datalist!</datalist> </select><slot id="select-datalist-options">: All other child elements of<select>which aren't assigned into the button or datalist slots. This slot is only rendered if the author doesn't provide a datalist element. Here is an example of author HTML which would use this slot:<select> <option>I am slotted into id=select-datalist-options!</option> <optgroup>I am also slotted into id=select-datalist-options!</optgroup> </select>
All of the elements here with the proprietary pseudo attribute are mapped to pseudo-elements so that they can be targeted by the author in CSS, but we can discuss that later as I'd like to scope this issue down to the general structure.
I believe that WebKit and Gecko don't currently have a ShadowRoot attached to <select>, but I'm not sure if this whole structure I've proposed is implementable without it. I am hoping that adding a ShadowRoot to <select> would not impact the existing behavior of appearance:auto/none <select> in WebKit/Gecko.
I would like to get a resolution that the above ShadowRoot structure and slotting algorithms for <select> should be used in order to support appearance:base-select.
@josepharhar how does the selected item fit into this?
<span pseudo="select-fallback-button-text"></span> has its text content replaced with the text content of the currently selected <option>. If the author provides their own <button> which is slotted into <slot id="select-button">, then the author can put <selectedoption> inside the <button> they provided.
Is there a specific issue to discuss the pseudo-elements? I think we want the same pseudo-elements for the "new" and "old" markup, which goes against the pseudo attributes suggested here, but it's a bit unclear if you wanted that discussion to be separate.
Is there a specific issue to discuss the pseudo-elements? I think we want the same pseudo-elements for the "new" and "old" markup, which goes against the pseudo attributes suggested here, but it's a bit unclear if you wanted that discussion to be separate.
I created this issue to get consensus on the idea of having a shadowroot with this structure and slotting algorithm which can be used for appearance:base, which seemed big enough to have its own discussion. I created another issue for pseudo elements here: https://github.com/w3c/csswg-drafts/issues/10462
I'm not sure about the inline <svg viewBox="0 0 20 16" fill="none"><path d="M4 6 L10 12 L 16 6"></path></svg> ... the icon needs to respond to writing modes. And we should make it easy to change via CSS.
Maybe injecting the disclosure-open counter style would work?
Instead of using an SVG, perhaps we could use a unicode character like this one instead? ⌄
The CSS Working Group just discussed [css-ui] DOM/Box structure for appearance:base-select, and agreed to the following:
RESOLVED: <select> internals can be represented with shadow DOM (but shadow DOM support is not required as long as the behavior is the same)RESOLVED: Accept shadow dom structure as proposed initial comment in the issue, except for the svg part and naming of pseudo elements. issues to be opened for those
The full IRC log of that discussion
<emilio> scribenick: emilio<emilio> chrishtr: we can mark as needs edit and once that's done that'd get review and get closed
<emilio> annevk: sounds good
<dbaron> (above was about the previous item on the agenda)
<emilio> jarhar: That's a proposal for base-select behavior and DOM structure
<emilio> ... higher level questions would be whether it'd be ok to use shadow dom for this
<emilio> ... the other thing would be that in chromium elements inside the shadow root for the base and auto appearance
<gregwhitworth> q?
<emilio> ... and switch based on the computed value
<emilio> ... wonder if that's acceptable
<emilio> annevk: I think shadow roots are fine for this, we have the precedent of <details>
<fantasai> +1 to avoiding a true dependency on the shadow DOM
<emilio> ... in theory an implementation could not use shadow root
<emilio> q+
<emilio> jarhar: that sounds promising
<emilio> ... it sounds like we can define this as a shadow root
<emilio> masonf: are we doing resolutions?
<fantasai> PROPOSED: <select> internals can be represented with shadow DOM
<masonf> +1
<dandclark> +1
<gregwhitworth> emilio: I wanted to clarify fantasai point, I think she's fine defining in terms of shadow DOM but in theory you can implement it with something else
<gregwhitworth> fantasai: yeah, that's exactly right we should define it using shadow but it's ok if the implementation does not use shadow DOM
<emilio> emilio: sounds good
<gregwhitworth> chrishtr: they need to end up with the same interoperable result
<emilio> chrishtr: it's not observable that there's a shadow root right?
<masonf> shady-dom
<emilio> jarhar: I think that's correct
<emilio> chrishtr: we can put a non-normative note in the spec about it being possibly implemented with other technology
<fantasai> PROPOSED: <select> internals can be represented with shadow DOM (but shadow DOM support is not required as long as the behavior is the same)
<emilio> gregwhitworth: so fine to go with Elika's resolution
<emilio> *?
<masonf> +1
<keithamus> +1
<emilio> RESOLVED: <select> internals can be represented with shadow DOM (but shadow DOM support is not required as long as the behavior is the same)
<emilio> jarhar: I want to also go through the slots and so on
<emilio> gregwhitworth: Should we resolve that in this issue or move that to a different one?
<emilio> annevk: the one concern from our side is about the `multiple` attribute
<emilio> ... without that we can agree to this
<emilio> ... but with `multiple` one of the slots ends up not being there or rendered
<emilio> jarhar: we can change the shadow DOM for the `multiple` attribute
<emilio> ack emilio
<gregwhitworth> ack fantasai
<emilio> jarhar: so that there's a shadow DOM but can be completely different
<chrishtr> q+
<emilio> fantasai: currently in html we combine two things, if you can select one it's a popup and otherwise it's an embedded control
<gregwhitworth> q+
<masonf> q+
<emilio> ... I think we can split that into multiple axes
<masonf> that's the multiple and size attributes, respectively.
<annevk> (modulo iOS where it's a little different from that even)
<gregwhitworth> ack chrishtr
<jarhar> q?
<lwarlow> (and android)
<emilio> ... so that we can make a popup where you can select multiple attributes, and you can have an embedded thing where you can select just one
<emilio> chrishtr: all those things can be figured out but can we leave those not defined yet?
<emilio> ... and define just the non-multiple case for now?
<emilio> fantasai: I think we might need to come back and change things once we tackle the others
<gregwhitworth> ack gregwhitworth
<gregwhitworth> ack masonf
<emilio> chrishtr: we can take an action item to dig into that to make sure that changes might not be needed
<emilio> masonf: there's `multiple` and `size` which theoretically create those two axes
<emilio> ... behavior is a bit different in mobile vs. not, I think there are a lot of issues with `multiple` without that
<gregwhitworth> q+
<emilio> ... so I think we need feature detection but I'd like not to block on that
<lwarlow> q+
<emilio> fantasai: I think that'd be surprising, I'd like multiple to be defined for styleable select
<emilio> ... I think you can't just ignore the semantics of `multiple`
<gregwhitworth> ack gregwhitworth
<emilio> masonf: I was thinking of just forcing `auto` rather than ignoring `multiple`
<lwarlow> q-
<emilio> fantasai: I think I worry about site issues once we start making changes there, I think it's solvable and we should fix it
<emilio> chrishtr: agree on solvable, I don't think it blocks resolving on jarhar's proposal for the single case
<emilio> fantasai: I think the structure makes sense except the svg
<emilio> ... because it doesn't respect writing-mode
<emilio> ... in respect on the names of pseudos we want to be consistent with other stuff we expect to do elsewhere
<jarhar> q?
<chrishtr> proposed: "accept shadow dom structure as proposed initial comment in the issue, except for svg part"
<emilio> ... but over-all structure makes sense otherwise
<fantasai> s/to do elsewhere, so probably should discuss separately/
<emilio> jarhar: for pseudo names I agree they're not great
<chrishtr> "pseudo element names to be decided later"
<emilio> ... there's another issue for that
<emilio> ... as for the SVG I agree, there's a similar discussion for checkmarks
<emilio> ... we moved to a unicode character
<emilio> ... there's a down arrow thing
<chrishtr> q+
<emilio> ... do you think using it would be reasonable
<emilio> fantasai: if you use disclosure-open then it takes care of those issues
<gregwhitworth> ack chrishtr
<dbaron> s/disclosure-open/the disclosure-open counter style/
<emilio> chrishtr: suggestion is to make some forward progress on this. We can discuss checkmarks / svg / names later
<emilio> gregwhitworth: I agree, follow-up issues for glyph and pseudo-elements makes sense
<chrishtr> "accept shadow dom structure as proposed initial comment in the issue, except for svg part and naming of pseudo elements. issues to be opened for those"
<emilio> fantasai: should probably be one issue for the pseudos and such, we should decide them together
<jarhar> i already created an issue for pseudo elements here: https://github.com/w3c/csswg-drafts/issues/10462
<masonf> +1
<gregwhitworth> q?
<chrishtr> "accept shadow dom structure as proposed in the initial comment in the issue, except for svg part and naming of pseudo elements. issues to be opened for those"
<emilio> fantasai: inside the button one of the elements is a `<span>` and another a `<div>`, why?
<gregwhitworth> RESOLVED: Accept shadow dom structure as proposed initial comment in the issue, except for the svg part and naming of pseudo elements. issues to be opened for those
<emilio> jarhar: good question, maybe I was relying on block vs inline layout, but I might be overriding display anyways
@fantasai noted that perhaps <div pseudo="select-fallback-button-icon"> should also be a span like <span pseudo="select-fallback-button-text">. I likely did this due to the UA styles of divs vs spans, and I agree it should probably be a span instead. The content of this part is also subject to change based on how we design the dropdown indicator to not be an svg
Instead of using an SVG, perhaps we could use a unicode character like this one instead? ⌄
The problem with using unicode characters is how to maintain consistency of presentation across OS?
I mentioned here the technique of using @font-face to load a custom font, not sure if it works inside the browser.
Maybe injecting the disclosure-open counter style would work?
I am implementing this in the prototype here: https://chromium-review.googlesource.com/c/chromium/src/+/5660759
I'm having a hard time getting select::select-fallback-button::after to work in author stylesheets, but other than that it seems good to me.
Maybe injecting the disclosure-open counter style would work?
@fantasai does this seem like what you were thinking of?
select::select-fallback-button::after {
padding-inline-start: 0.5em;
}
select:open::select-fallback-button::after {
content: counter(foo, disclosure-open);
}
select:not(:open)::select-fallback-button::after {
content: counter(foo, disclosure-closed);
}
Maybe injecting the disclosure-open counter style would work?
@fantasai does this seem like what you were thinking of?
select::select-fallback-button::after { padding-inline-start: 0.5em; } select:open::select-fallback-button::after { content: counter(foo, disclosure-open); } select:not(:open)::select-fallback-button::after { content: counter(foo, disclosure-closed); }
I'm going to implement this in the prototype now before re-architecting the button in response to https://github.com/w3c/csswg-drafts/issues/10717
The pseudo-elements and UA styles mentioned in my last two comments were futher refined and resolved in further discussions in the sub-issues here, so I'm going to close this: https://github.com/whatwg/html/issues/9799