Skip to content
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

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

Open
josepharhar opened this issue May 30, 2024 · 13 comments
Open

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

josepharhar opened this issue May 30, 2024 · 13 comments

Comments

@josepharhar
Copy link
Contributor

josepharhar commented May 30, 2024

Now that we have decided in #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.

@annevk
Copy link
Member

annevk commented Jun 14, 2024

@josepharhar how does the selected item fit into this?

@josepharhar
Copy link
Contributor Author

<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
Copy link
Member

annevk commented Jun 14, 2024

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
Copy link
Contributor Author

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: #10462

@fantasai
Copy link
Collaborator

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
Copy link
Collaborator

Maybe injecting the disclosure-open counter style would work?

@josepharhar
Copy link
Contributor Author

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

@css-meeting-bot
Copy link
Member

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//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
Copy link
Contributor Author

@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
Copy link
Contributor

yisibl commented Jun 28, 2024

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
Copy link
Contributor Author

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
Copy link
Contributor Author

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
Copy link
Contributor Author

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 #10717

chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Aug 19, 2024
This was suggested here:
w3c/csswg-drafts#10380 (comment)

This patch also adds min-inline-size and min-block-size to
::select-fallback-button because changing the icon caused the total size
of the button to decrease which revealed the lack of min sizing which is
already tested by
select-accessibility-minimum-target-size.tentative.html

Bug: 1511354
Change-Id: Id7b3b0aa6c9c79299240a7212023f849f3703fb0
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Aug 27, 2024
This was suggested here:
w3c/csswg-drafts#10380 (comment)

This patch also adds min-inline-size and min-block-size to
::select-fallback-button because changing the icon caused the total size
of the button to decrease which revealed the lack of min sizing which is
already tested by
select-accessibility-minimum-target-size.tentative.html

The UA select:open rules caused a performance regression for large
<select>s because it caused a style recalc immediately after opening the
appearance:auto picker which in re-serializes all of the data for the
popup and sends it to the popup, which is very slow for large selects. I
addressed this by starting to match :open before creating the popup in
MenuListSelectType::ShowPopup.

Bug: 1511354
Change-Id: Id7b3b0aa6c9c79299240a7212023f849f3703fb0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5660759
Commit-Queue: Joey Arhar <jarhar@chromium.org>
Reviewed-by: David Baron <dbaron@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1347324}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Aug 27, 2024
This was suggested here:
w3c/csswg-drafts#10380 (comment)

This patch also adds min-inline-size and min-block-size to
::select-fallback-button because changing the icon caused the total size
of the button to decrease which revealed the lack of min sizing which is
already tested by
select-accessibility-minimum-target-size.tentative.html

The UA select:open rules caused a performance regression for large
<select>s because it caused a style recalc immediately after opening the
appearance:auto picker which in re-serializes all of the data for the
popup and sends it to the popup, which is very slow for large selects. I
addressed this by starting to match :open before creating the popup in
MenuListSelectType::ShowPopup.

Bug: 1511354
Change-Id: Id7b3b0aa6c9c79299240a7212023f849f3703fb0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5660759
Commit-Queue: Joey Arhar <jarhar@chromium.org>
Reviewed-by: David Baron <dbaron@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1347324}
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Aug 28, 2024
…open, a=testonly

Automatic update from web-platform-tests
Replace base-select svg with disclosure-open

This was suggested here:
w3c/csswg-drafts#10380 (comment)

This patch also adds min-inline-size and min-block-size to
::select-fallback-button because changing the icon caused the total size
of the button to decrease which revealed the lack of min sizing which is
already tested by
select-accessibility-minimum-target-size.tentative.html

The UA select:open rules caused a performance regression for large
<select>s because it caused a style recalc immediately after opening the
appearance:auto picker which in re-serializes all of the data for the
popup and sends it to the popup, which is very slow for large selects. I
addressed this by starting to match :open before creating the popup in
MenuListSelectType::ShowPopup.

Bug: 1511354
Change-Id: Id7b3b0aa6c9c79299240a7212023f849f3703fb0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5660759
Commit-Queue: Joey Arhar <jarhar@chromium.org>
Reviewed-by: David Baron <dbaron@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1347324}

--

wpt-commits: 8108d046baa2bb0a947617b52dd568f59ec7c27f
wpt-pr: 47672
ErichDonGubler pushed a commit to erichdongubler-mozilla/firefox that referenced this issue Aug 29, 2024
…open, a=testonly

Automatic update from web-platform-tests
Replace base-select svg with disclosure-open

This was suggested here:
w3c/csswg-drafts#10380 (comment)

This patch also adds min-inline-size and min-block-size to
::select-fallback-button because changing the icon caused the total size
of the button to decrease which revealed the lack of min sizing which is
already tested by
select-accessibility-minimum-target-size.tentative.html

The UA select:open rules caused a performance regression for large
<select>s because it caused a style recalc immediately after opening the
appearance:auto picker which in re-serializes all of the data for the
popup and sends it to the popup, which is very slow for large selects. I
addressed this by starting to match :open before creating the popup in
MenuListSelectType::ShowPopup.

Bug: 1511354
Change-Id: Id7b3b0aa6c9c79299240a7212023f849f3703fb0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5660759
Commit-Queue: Joey Arhar <jarhar@chromium.org>
Reviewed-by: David Baron <dbaron@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1347324}

--

wpt-commits: 8108d046baa2bb0a947617b52dd568f59ec7c27f
wpt-pr: 47672
i3roly pushed a commit to i3roly/firefox-dynasty that referenced this issue Aug 29, 2024
…open, a=testonly

Automatic update from web-platform-tests
Replace base-select svg with disclosure-open

This was suggested here:
w3c/csswg-drafts#10380 (comment)

This patch also adds min-inline-size and min-block-size to
::select-fallback-button because changing the icon caused the total size
of the button to decrease which revealed the lack of min sizing which is
already tested by
select-accessibility-minimum-target-size.tentative.html

The UA select:open rules caused a performance regression for large
<select>s because it caused a style recalc immediately after opening the
appearance:auto picker which in re-serializes all of the data for the
popup and sends it to the popup, which is very slow for large selects. I
addressed this by starting to match :open before creating the popup in
MenuListSelectType::ShowPopup.

Bug: 1511354
Change-Id: Id7b3b0aa6c9c79299240a7212023f849f3703fb0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5660759
Commit-Queue: Joey Arhar <jarhar@chromium.org>
Reviewed-by: David Baron <dbaron@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1347324}

--

wpt-commits: 8108d046baa2bb0a947617b52dd568f59ec7c27f
wpt-pr: 47672
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants