w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.5k stars 660 forks source link

[css-ui] DOM/Box structure for appearance:base-select #10380

Open josepharhar opened 5 months ago

josepharhar commented 5 months ago

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:

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.

annevk commented 4 months ago

@josepharhar how does the selected item fit into this?

josepharhar commented 4 months ago

<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.

annevk commented 4 months ago

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.

josepharhar commented 4 months ago

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

fantasai commented 4 months ago

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.

fantasai commented 4 months ago

Maybe injecting the disclosure-open counter style would work?

josepharhar commented 4 months ago

Instead of using an SVG, perhaps we could use a unicode character like this one instead? ⌄

css-meeting-bot commented 4 months ago

The CSS Working Group just discussed [css-ui] DOM/Box structure for appearance:base-select, and agreed to the following:

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
josepharhar commented 4 months ago

@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

yisibl commented 4 months ago

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.

josepharhar commented 3 months ago

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.

josepharhar commented 2 months ago

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);
}
josepharhar commented 2 months ago

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