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] UA stylesheet for appearance:base <select> #10857

Open
josepharhar opened this issue Sep 9, 2024 · 29 comments
Open

[css-ui] UA stylesheet for appearance:base <select> #10857

josepharhar opened this issue Sep 9, 2024 · 29 comments
Labels

Comments

@josepharhar
Copy link
Contributor

josepharhar commented Sep 9, 2024

I'd like to propose a UA stylesheet for <select> which applies when the <select> has size=1, no multiple attribute, and appearance:base.

Based on the discussion here and the proof of concept in the chromium prototype I implemented, we can make these styles only apply when <select> has appearance:base.

Styles from #10908 - the names were resolved, but not necessarily the properties:

select option::checkmark {
  content: '\2713' / '';
}
select option:not(:checked)::checkmark {
  visibility: hidden;
}
select::picker-icon {
  /* margin-inline-start pushes the icon to the right of the box */
  margin-inline-start: auto;
  display: block;
  content: counter(fake-counter-name, disclosure-open);
}

Styles from #10909

select {
  border: 1px solid currentColor;
  background-color: color-mix(in lab, currentColor 10%, transparent);
  color: inherit;
}
select:enabled:hover {
  background-color: color-mix(in lab, currentColor 20%, transparent);
}
select:enabled:active  {
  background-color: color-mix(in lab, currentColor 30%, transparent);
}
select:disabled {
  color: color-mix(in srgb, currentColor 50%, transparent);
}

::picker(select) {
  /* Same properties as popover and dialog */
  color: CanvasText;
  background-color: Canvas;
  border: 1px solid;
}

select option:enabled:hover {
  background-color: color-mix(in lab, currentColor 20%, transparent);
}
select option:enabled:active {
  background-color: color-mix(in lab, currentColor 30%, transparent);
}
select option:disabled {
  color: color-mix(in lab, currentColor 50%, transparent);
}

Remaining properties to be resolved on:

select {
  /* Padding prevents the text from sticking to the borders.
   * optically centered to account for half leading */
  padding-block: 0.25em;
  padding-inline: 0.5em;

  /* Match <button> */
  border-radius: 0.25em;

  /* These min-size rules ensure accessibility by following WCAG rules:
   * https://www.w3.org/WAI/WCAG22/Understanding/target-size-minimum.html
   * The 1.2em is there to make sure that options without text don't change
   * the block size of the button. */
  min-block-size: max(24px, 1lh);
  min-inline-size: 24px;

  /* box-sizing comes from existing UA styles which happen to
   * already be interoperable. */
  box-sizing: border-box;

  /* Push picker icon to the right of the box and have some space
   * in between it and the text. */
  display: inline-flex;
  gap: 1em;
}

select > button:first-child {
  /* Prevents button from setting font, color, or background-color */
  all: unset;

  /* Prevents duplicate box decorations */
  display: contents;

  /* Prevents button activation behavior so select can handle events */
  interactivity: inert;
}

select::picker(select) {
  /* box-sizing is set to match the button. */
  box-sizing: border-box;

  /* Scrollbars in the picker are OK */
  overflow: auto;

  /* Remove [popover] padding which
   * prevents options from extending to edges */
  padding: 0;

  /* Match <select> */
  border-radius: 0.25em;

  /* Anchor positioning */
  inset: auto;
  margin: 0;
  min-inline-size: anchor-size(self-inline);
  min-block-size: 1lh;
  position-area: block-end span-inline-end;
  position-try-fallbacks:
    block-start span-inline-end,
    block-end span-inline-start,
    block-start span-inline-start;
}

select option {
  /* These min-size rules ensure accessibility by following WCAG rules:
   * https://www.w3.org/WAI/WCAG22/Understanding/target-size-minimum.html
   * Unset if the author provides a child button element.
   * The 1lh is there to make sure that options without text don't change
   * the block size of the option. */
  min-inline-size: 24px;
  min-block-size: max(24px, 1lh);

  /* Centers text within the block (vertically). From OpenUI discussion:
   * https://github.com/openui/open-ui/issues/1026#issuecomment-2103187647. */
  align-content: center;

  /* centering + gap between checkmark and option content */
  /* also easily reversed, when checkmark should be inline-end */
  display: flex;
  place-items: center;
  gap: 0.5em;

  /* Makes options with long text widen picker instead
   * of making options tall. */
  white-space: nowrap;
}

select optgroup {
  /* font-weight makes optgroups visually distinct from options. */
  font-weight: bolder;
}

select optgroup option {
  /* Undo font-weight:bolder rule from optgroups. */
  font-weight: normal;
}

select legend,
select option {
  /* spacing ownership moves to children */
  /* space inline from border edges */
  /* this creates a full bleed hover highlight */
  padding-inline: 0.5em;
}
@nt1m
Copy link
Member

nt1m commented Sep 10, 2024

I would prefer punting this until we've discussed general design principles for appearance: base in #10866 which would influence this issue somewhat. I really believe thinking about this holistically aside outside of just one single form control is important to not repeat mistakes that were previously done.

@nt1m
Copy link
Member

nt1m commented Sep 13, 2024

Some feedback:

  • The checkmark icon deserves its own pseudo (::check? maybe, something that's reusable with for checkbox/radios)
  • The dropdown icon deserves its own pseudo (::select-arrow? not super convinced by the name myself, but 🤷 )
  • select::picker(select) -> ::picker(select)
  • Styles should be minimal: ::picker() probably shouldn't include a box-shadow
  • There's a lot of uses of system colors, I know that's prior art, but we're thinking of dropping that for appearance: base across the board, since in 100% of the cases, people want to override it
  • There's use of custom fonts, we're also thinking appearance: base should probably just inherit the font for all controls since a custom font probably one of the annoying defaults for form controls.

The last 2 points somewhat link to #10866 , and it might be good to discuss this in person at TPAC to find a set of consistent approaches to make this work holistically across all controls. We have many more ideas that are not covered by this comment alone

@mfreed7
Copy link
Contributor

mfreed7 commented Sep 13, 2024

I would prefer punting this until we've discussed general design principles for appearance: base in #10866 which would influence this issue somewhat. I really believe thinking about this holistically aside outside of just one single form control is important to not repeat mistakes that were previously done.

Love this approach, by the way. I think it's a great idea to set down some guiding principles that we can refer back to as we design all of the controls. I added a few comments on #10866 (comment).

  • The checkmark icon deserves its own pseudo (::check? maybe, something that's reusable with for checkbox/radios)

Makes sense. We were fairly conflicted on the use of ::before. One possibility is ::marker but that's got other restrictions that might not make sense for <select> use cases. So maybe ::check or ::checkmark.

  • The dropdown icon deserves its own pseudo (::select-arrow? not super convinced by the name myself, but 🤷 )

Makes sense.

  • select::picker(select) -> ::picker(select)

Agree.

  • Styles should be minimal: ::picker() probably shouldn't include a box-shadow

Likely fine, though the drop-shadow does help users distinguish that this is a popover picker "above" the in-page display. Perhaps we could find a less opinionated set of values?

  • There's a lot of uses of system colors, I know that's prior art, but we're thinking of dropping that for appearance: base across the board, since in 100% of the cases, people want to override it

The really nice thing about system colors, though, is that they handle dark mode. We believe the defaults for all controls should work well in both light and dark mode. Instead of system colors, we could use light-dark() but that just feels like more work for not much benefit, when the system colors do that already.

  • There's use of custom fonts, we're also thinking appearance: base should probably just inherit the font for all controls since a custom font probably one of the annoying defaults for form controls.

Makes sense, and agree with the annoying defaults comment.

@nt1m
Copy link
Member

nt1m commented Sep 13, 2024

One possibility is ::marker but that's got other restrictions that might not make sense for <select> use cases.

::marker is linked to display: list-item; so unless we want to make <option> element list-items, I'm not sure it's appropriate. Maybe @fantasai has opinions here :)

The really nice thing about system colors, though, is that they handle dark mode. We believe the defaults for all controls should work well in both light and dark mode. Instead of system colors, we could use light-dark() but that just feels like more work for not much benefit, when the system colors do that already.

There are alternatives that work in dark mode that don't involve light-dark() / system colors, while allowing easy overrides. We can probably discuss this in person at TPAC.

@lukewarlow
Copy link
Member

lukewarlow commented Sep 16, 2024

Colours chosen have other configs to potentially account for such as contrast preferences. One other benefit of system colours beyond just light and dark is they automatically adjust when using forced colors mode too. While it's likely to be overridden in most cases, it's possible that base appearance is used in a CSS reset but not actively overridden and imo (though others may disagree) we should make the default base styles as accessible and usable as possible, while maintaining the customisability.

As mentioned though there's alternatives to system colours.

@tabatkins
Copy link
Member

The checkmark icon deserves its own pseudo (::check? maybe, something that's reusable with for checkbox/radios)

Could you elaborate on why this is? I don't necessarily object to having a specialized pseudo-element, but the reason we've avoided using ::before/::after in the past for CSS-defined things is the potential for it to conflict with existing author-provided code using those pseudos. That isn't the case here - these are brand new elements, impossible to target by any existing CSS no matter how general.

@nt1m
Copy link
Member

nt1m commented Sep 16, 2024

The checkmark icon deserves its own pseudo (::check? maybe, something that's reusable with for checkbox/radios)

Could you elaborate on why this is? I don't necessarily object to having a specialized pseudo-element, but the reason we've avoided using ::before/::after in the past for CSS-defined things is the potential for it to conflict with existing author-provided code using those pseudos. That isn't the case here - these are brand new elements, impossible to target by any existing CSS no matter how general.

The developer might choose ::before / ::after to do something else with it (add emojis? fancy selected option indicator? add a counter?), if they find out they need to override the default UA stylesheet usage, it's not really a great experience.

@josepharhar
Copy link
Contributor Author

josepharhar commented Sep 17, 2024

Thanks for the discussion! I created separate issues for pseudo-elements and colors:

There's use of custom fonts, we're also thinking appearance: base should probably just inherit the font for all controls since a custom font probably one of the annoying defaults for form controls.

So should we set all of the font longhands to inherit? Or initial or another special value? What is "the font for all controls"?

@fantasai
Copy link
Collaborator

Set the font properties to unset if you need to; they inherit by default, so ideally just leave them alone.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-ui] UA stylesheet for appearance:base `<select>` , and agreed to the following:

  • RESOLVED: font properties won't be set in the UA style sheet
The full IRC log of that discussion <chrishtr> jarhar: there has been good discussion in the issue, and I've created two sub-issues for some topics
<chrishtr> jarhar: don't know if there is anything specific to resolve in the issue right now?
<chrishtr> fantasai: we could resolve to inherit the font?
<dbaron> yeah, +1 to inheriting the font
<chrishtr> ntim: think it could be good to delay this discussion to after or during TPAC
<chrishtr> fantasai: agree in general
<chrishtr> q+
<chrishtr> fantasai: also for all form controls and not just select
<astearns> ack fantasai
<chrishtr> jensimmons: would be best to discuss then/later
<chrishtr> jarhar: I'd like to discuss things like which pseudo elements we should add, how to specify colors, ...
<chrishtr> fantasai: let's reschedule so that the breakout is first?
<chrishtr> astearns: we could have tentative discussions at the breakout and then finalize them at the group later
<fantasai> s/breakout is first/breakout agenda is rescheduled into the OpenUI joint meeting/
<sanketj_> https://github.com/whatwg/meta/issues/326
<keithamus> scribe+
<keithamus> chrishtr: while we do want consistent styles, `<select>` is being worked on this year and we need to ensure we don't unreasonably delay decisions based on that.
<keithamus> chrishtr: we can use it as a place to set precedent for the others
<keithamus> astearns: So here is the precedent, but if we make a mistake we can change them as we integrate into the larger set?
<keithamus> chrishtr: sure we can make changes later.
<ntim> (can't talk right now) I'm hoping that TPAC gives enough time to resolve most things regarding UA stylesheets! My goal is more to help drive select's direction not block its progress :)
<jarhar> +1 to using unset for font properties
<ntim> (or not setting the font at all)
<chrishtr> RESOLVED: font properties won't be set in the UA style sheet
<chrishtr> jarhar: this issue was created because accessibility experts are concerned about authors ending up with inaccessibile structures
<fantasai> i/jarhar:/Topic: Content Model/
<fantasai> github: https://github.com/whatwg/html/issues/10317
<chrishtr> jarhar: we should discuss which are allowed so as to preserve accessibility. I worked with accessibility experts from OpenUI and came up with a list of elements which should be allowed within select: divs, spans, img, text within options but outside
<RRSAgent> I have made the request to generate https://www.w3.org/2024/09/19-css-minutes.html fantasai
<chrishtr> jarhar: and legend elements as child of optgroup to replace label
<chrishtr> jarhar: this has the same a11y mapping but is more styleable
<jarhar> q?
<astearns> ack chrishtr
<emilio> q+
<chrishtr> jarhar: my HTML spec PR is ready to go so from my perspective it's ready. should we go with this approach?
<astearns> ack emilio
<chrishtr> emilio: curious if we're going to have special rendering for legend like we have for fieldset, or are there any other special rendering rules?
<astearns> pr: https://github.com/whatwg/html/pull/10586
<chrishtr> emilio: if you put a legend into a fieldset the the rendering is quite special. the first thing gets moved up to the top regardless of where it is in the DOM, and other layout tree reparenting.
<chrishtr> emilio: hoping we don't have to do any of that
<astearns> q+
<chrishtr> jarhar: my preference is also not to do anything special. didn't come across any need to have special rendering in prototyping in Chromium. I just set up the a11y mappings and changed the rendering of the optgroup element so it would stop rendering the label attribute part when there is a legend child
<chrishtr> fantasai: on the PR: it says div and span, but not various other elements like em or bdo. why not?
<chrishtr> jensimmons: there are so many other elements that seem reasonable?
<chrishtr> fantasai: ruby also
<chrishtr> jarhar: these are good points and should be included within option elements. these rules are about content outside option elements.
<astearns> ack fantasai
<chrishtr> jarhar: maybe we can use a more broad rule for inside-option parts
<chrishtr> fantasai: span or other inline elements don't belong outside option
<chrishtr> fantasai: div allowed but not span because span is inline
<chrishtr> astearns: are there tests?
<chrishtr> jarhar: the tests for the content model: not sure how to do that. in the Chromium implementation, we render everything but use developer tooling to guide people towards accessible outcomes. tl;dr I don't know how to test it in WPT.
<astearns> ack astearns
<astearns> zakim, end meeting

@josepharhar
Copy link
Contributor Author

I took @nt1m's styles from webkit for buttons and put them in the OP, as well as our last resolution on inheriting fonts.

@josepharhar
Copy link
Contributor Author

Based on the discussions so far, it sounds like we probably shouldn't have a box shadow, so I am removing that from the proposed styles in the OP. I'm also replacing ::before and ::after with ::check and ::select-arrow

aarongable pushed a commit to chromium/chromium that referenced this issue Oct 2, 2024
Context: w3c/csswg-drafts#10857 (comment)

Change-Id: I775eb75e77d2d4cb5a3a849a705baccc93f65f3e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5906260
Reviewed-by: Traian Captan <[email protected]>
Auto-Submit: Joey Arhar <[email protected]>
Commit-Queue: Traian Captan <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1363348}
josepharhar added a commit to josepharhar/html that referenced this issue Oct 3, 2024
@josepharhar
Copy link
Contributor Author

I updated the issue description to separate the styles which are being discussed/resolved in other issues and the styles which still need review/resolutions. Please take a look and let me know if yall have any recommendations!

@josepharhar
Copy link
Contributor Author

I added comments to all of the properties in the "still need review/resolutions" portion of UA styles in the issue description. Please take a look!

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-ui] UA stylesheet for appearance:base `<select>` .

The full IRC log of that discussion <chrishtr> jarhar: have a list of additional properties proposed for the UA stylesheet. Think we should just go through them one-by-one.
<chrishtr> first rule: padding: 025em
<chrishtr> without this rule, the text in the button would stick to the borders, this centers it
<chrishtr> there is a caveat that it changes to 0 if the developer provides a child button element. That is there because if the the developer provides it, then we should just use that button and not add on extra box deccoration
<chrishtr> emilio: the select has a border right?
<chrishtr> jarhar: going to propose to remove the border actually
<chrishtr> jarhar: that way you don't have two borders
<chrishtr> jarhar: this was discussed on a separate issue with tim
<jensimmons> q+
<astearns> ack fantasai
<emilio> q+
<chrishtr> fantasai: what is the box model we're trying to style in this case? what boxes exist and what formatting context does it have? Is the select a bock box or a flexbox.
<chrishtr> jarhar: display: inline-block should answer that question (there is a proposed UA rule for it)
<chrishtr> fantasai: and it directly contains text? and if there is a provided button it shows the button?
<chrishtr> fantasai: there was a discussion about a pseudo elements, where did that go?
<chrishtr> jarhar: we decided not to have a fallback UA pseudo element in this case, and instead the select element itself should be it
<chrishtr> fantasai: if there is a button element, is block layout what you want for it? don't think so because we want the button to align with the border right?
<chrishtr> jarhar: yes
<chrishtr> jarhar: think we could do several adjustments if the button is there
<annevk> (display: contents might make focus funky too)
<chrishtr> fantasai: from an author's perspective should not see things change just because you added markup
<masonf> What if we add `select>button {border:0; padding:0}` instead? And leave select's borders and padding.
<emilio> `select > button { display: contents }`? :)
<astearns> ack jensimmons
<fantasai> or maybe select > button { display: contents; }
<chrishtr> jensimmons: interesting that we have styling that depends on content
<chrishtr> jensimmons: don't know of another case that works that way
<chrishtr> jensimmons: not sure if authors would be confused by that or not
<chrishtr> jensimmons: for the sake of these conversations more visuals would be n ice
<astearns> q+
<chrishtr> jensimmons: don't know what to think right now but want to help get it done, there might be bikeshedding.
<masonf> Some common examples and use cases are detailed here: https://developer.chrome.com/blog/rfc-customizable-select
<chrishtr> jensimmons: can't tell
<astearns> ack emilio
<chrishtr> emilio: maybe the button shouldn't have decorations and should delegate that to the select element. display:contents on the button
<chrishtr> emilio: that may be a simpler option that avoids magic
<chrishtr> emilio: also have feedback on the min sizing
<keithamus> q+
<chrishtr> emilio: 24px may be too big
<chrishtr> emilio: white-space: normal seems find
<chrishtr> emilio: 2px block and 1px inline padding already exists?
<chrishtr> emilio: overall, the fewer rules the better
<chrishtr> emilio: display:contents could explain has behavior
<annevk> q+ to bring up the topic of how this relates to base styling of other controls
<masonf> q+
<chrishtr> emilio: maybe also make it !important
<astearns> ack fantasai
<chrishtr> fantasai: agree display: contents on the button make sense
<chrishtr> fantasai: no need for !important
<chrishtr> fantasai: considering pixel values for padding, I am in favor of em because it'll scale with font sizing
<chrishtr> fantasai: font-relative is good
<annevk> (.25em seems quite big, that's 4px)
<chrishtr> fantasai: not sure why 0.25, where did that come from?
<fantasai> s/0.25/1.2em/
<dbaron> many of these things are based on the existing UA stylesheet rules for <select>
<chrishtr> emilio: agree that em paddings are nicer. but also think that if we can avoid making different appearance:base specific CSS values that's better. the less differences the better.
<chrishtr> emilio: if existing padding is ok then let's try to accept it
<jarhar> q?
<jensimmons> q+
<chrishtr> astearns: uncomfortable with having a switch on select content that is not expressed in the UA stylesheet
<emilio> `select:has(> button) { ... }` should work
<chrishtr> astearns: if we have things in the UA style sheet that depends on some state we should avoid that and fix it
<astearns> ack astearns
<ntim> I like Elika's suggestion of making button display: contents
<annevk> (I agree with that to an extent, there's definitely things that are just not worth generalizing to CSS syntax.)
<jensimmons> Totally agree with Alan — secretly putting a switch to the styles in the engine is even more magical. It can totally be done in CSS.
<chrishtr> keithamus: in favor of the rule as it stands. 24px minimum size is useful. should consider a11y, and WCAG recommends that
<chrishtr> keithamus: I'd prefer even larger but smaller gets quite problematic
<masonf> Rule #3 here says we need to follow WCAG: https://github.com//issues/10866
<annevk> (E.g., detecting iso-8859-8-i.)
<chrishtr> keithamus: 0.25em is also good, a lot of design systems use it
<chrishtr> keithamus: need good defaults for modern-day practices and a11y practices. This is an opportunity to set good defaults.
<astearns> +1 to not always following current styling
<fantasai> strong +1 to keithamus
<chrishtr> keithamus: should avoid making it too complicated, but since it's easy for authors to customize it doesn't get in their way
<annevk> Can't it just be `select > button`?
<chrishtr> keithamus: display: contents is problematic, might be confusing to developers. also might have a11y problems
<chrishtr> keithamus: if you have a button in the select then probably the button should be in the AT, but if it's display:contents that would mess this up
<astearns> q?
<astearns> ack keithamus
<astearns> ack annevk
<Zakim> annevk, you wanted to bring up the topic of how this relates to base styling of other controls
<chrishtr> annevk: one meta point is that as we decide on these rules it'll have implications for base styles for other controls
<chrishtr> annevk: if we decide padding or sizing here then it should make sense for other controls
<chrishtr> annevk: don't want to have to revisit for other form controls
<chrishtr> annevk: with regards to display: contents, there are a lot of implications of display: contents for focus and so on that make it tricky
<chrishtr> annevk: if you just use a child selector then we could override its border and padding to be 0?
<emilio> So `select > button { appearance: none; padding: 0; border: 0 }`?
<chrishtr> annevk: if you're styling this button will its appearance be?
<astearns> ack masonf
<chrishtr> mason: one rule we're following is to follow WCAG, which is where 24px came from
<chrishtr> s/mason/masonry/
<chrishtr> s/mason/masonf/
<chrishtr> masonf: agree that we could have a rule like what Emilio wrote to remove appearance and put 0 padding and border
<jensimmons> q-
<chrishtr> jarhar: the way we implemented it is that if the button is present then focus delegates to it, including focus rings
<chrishtr> jarhar: if there is no button then the select element itself gets the focus
<emilio> display: contents on the button seems like a nicer fix for the focus issue tbh :)
<emilio> q+
<chrishtr> masonf: others said let's inherit padding when possible from appearance: auto. I think we should fix them to be good.
<astearns> ack fantasai
<Zakim> fantasai, you wanted to disagree with emilio, our priority should be to be a good, accessible, interoperable base for styling, not consistent with existing styles
<annevk> I think if the `button` is being styled in the UA style sheet we need to figure out `appearance: base` for it.
<astearns> +1 to not making !important rules in the UA stylesheet if we can avoid it
<annevk> (I use webirc.w3.org and it keeps dropping me from the channel. I wish we'd use something that's not IRC.)
<chrishtr> fantasai: wanted to agree with Mason's sentiment that we should not optimize for avoiding rules that override auto, we should instead make a good and consistent base style without worrying about auto
<keithamus> q+
<chrishtr> fantasai: the button stuff sounds really confusing, since if you have a button you have to style that and not the select, and if not the select.
<chrishtr> fantasai: the button should be a markup extra that somehow doesn't need that complication
<astearns> ack emilio
<chrishtr> fantasai: if the purpose of the button is to clarify hierarchies then limit to that, and make it display: contents !important
<chrishtr> emilio: happy to concede on the padding
<fantasai> +1 emilio
<chrishtr> emilio: the focus shenanigans: display: contents would be simpler. then the rules for outlines would be simpler, since you'd always focus the select and not the button
<astearns> ack keithamus
<chrishtr> keithamus: one thing we might consider is that this is going to get integrated into sites that already have a lot of CSS, including around buttons
<chrishtr> keithamus: they will also have CSS around focus, active, etc
<masonf> q+
<chrishtr> keithamus: making the button a transparent part of the select might be a moot point, because the author is going to have button styling already in their theme, which they'd have to undo
<astearns> ack masonf
<chrishtr> masonf: following on that, if it was a custom element, you'd likely do the thing where you delegate styling. feels odd to have HTML that has a button and the button is not a regular button
<jarhar> q?
<chrishtr> masonf: display: contents seems weird from that perspective
<jarhar> q+
<ntim> q+
<astearns> ack jarhar
<annevk> What's the use case for the custom button? How does display: contents not invalidate that use case?
<chrishtr> jarhar: back when we were working on earlier iterations for this project, there was a way to put anything you want into the slot. now that I'm hearing people express concerns about different ways to handle this button, I'm thinking the original model was quite nice. could we go back to that?
<chrishtr> jarhar: we can't reuse the slot element, but maybe a new element or concept?
<jensimmons> No, we should use <button> not a <div> + new slot thing.
<chrishtr> annevk: the slot API is a web developer API.
<jensimmons> q+
<chrishtr> annevk: don't care about the button element that much, it's the content?
<chrishtr> annevk: maybe an appearance:base button could help?
<astearns> ack ntim
<chrishtr> ntim: before thinking about the styles with the button case, want to step back - what use cases will people use buttons for?
<chrishtr> ntim: if it's used for a split button then display: contents is probably not right
<keithamus> q+
<chrishtr> ntim: would be nice to see a list of use cases
<masonf> Some examples with custom buttons here: https://developer.chrome.com/blog/rfc-customizable-select
<chrishtr> jarhar: the main purpose of the button is to allow the developer to provide a way to put anything they want in the base element
<chrishtr> jarhar: a big use case is declaratively copying the selected option into the button
<chrishtr> jarhar: without providing them with a button, it precludes them putting their own or rich content into the in-page select element part
<chrishtr> jarhar: without doing this we'll miss most use cases
<masonf> q+
<chrishtr> ntim: does it allow for split buttons?
<chrishtr> jarhar: there has been a lot of discussion at OpenUI with experts
<annevk> q+ why do we need both button and selectedoption?
<annevk> q+ to ask why do we need both button and selectedoption?
<chrishtr> jarhar: split buttons have different a11y mapping, and they recommend using a completely different element for that, so split buttons is out of scope at the moment
<astearns> ack jensimmons
<chrishtr> jensimmons: an interesting thing about this project is understanding what it means to make a UA stylesheet. definitely think padding should be font-dependent. But if I we designing a design system I'd use line height units.
<chrishtr> jensimmons: we're trying to fix some decisions made back in the 90s
<annevk> q-
<chrishtr> jensimmons: we're not making the world's best design system though, just providing a base styling. might not be the perfect thing for them, but to find a way to match the new with the old
<chrishtr> jensimmons: without confusing authors
<astearns> ack keithamus
<chrishtr> keithamus: to extend on that point, we're not building this for people who are building on design systems or building a design system, these are defaults. design systems will very likely override most of these.
<chrishtr> keithamus: need to make sure it has accessible defaults, and that the styles aren't too difficult to override
<ntim> If the only use case is for the button is selectedoption, it makes sense to me from a styling perspective that button gets `display: contents`
<astearns> ack masonf
<fantasai> In that case, wouldn't you just style select { display: flex; } ?
<chrishtr> masonf: roughly +1 to what jen and keith said. agree authors will reset it. Minimal is better.
<chrishtr> masonf: we've been staring at this screen for an hour, but it's a quarter of the entire proposed style sheet
<chrishtr> masonf: suggest we iterate in the issue instead of live
<keithamus> it might be worth testing it against a bunch of popular CSS Reset libraries to ensure they don't break it in bad ways
<chrishtr> astearns: want to amplify Joey's point that the justification is in the comment, please reply on the issue

@annevk
Copy link
Member

annevk commented Nov 8, 2024

One thing that this illustrates to me is that we need to think about the other controls as well as we don't want the styles for select to be inconsistent with button for instance. (And in fact we potentially have to figure out button in order to allow it to be nested inside select.)

@josepharhar
Copy link
Contributor Author

josepharhar commented Nov 11, 2024

Based on the discussion last week, I made the following changes:

  • Set display:contents on the button in order to remove duplicate box decorations as a replacement for removing box decorations for the select element when there is a child button because changing styles based on the child button got negative feedback.
  • Set interactivity:inert on the button (made possible by this resolution) in order to move event handling from the button to the select element. This also allows us to remove a bunch of hacks to make the button work, such as using delegatesFocus on the select element, in Define base appearance for <select> whatwg/html#10629

chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Nov 14, 2024
This patch makes the <select> element itself handle focus, interaction,
and box decorations instead of the child <button> element. This removes
a lot of complexity, including delegatesFocus, divergent event handling
and button testing, and :-internal-select-has-child-button.

This was discussed here:
w3c/csswg-drafts#10857

Change-Id: Ia036c6dc08be1b86a50bd96239d08ad19c9a7a6b
aarongable pushed a commit to chromium/chromium that referenced this issue Nov 14, 2024
This patch makes the <select> element itself handle focus, interaction,
and box decorations instead of the child <button> element. This removes
a lot of complexity, including delegatesFocus, divergent event handling
and button testing, and :-internal-select-has-child-button.

This was discussed here:
w3c/csswg-drafts#10857

Change-Id: Ia036c6dc08be1b86a50bd96239d08ad19c9a7a6b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6001193
Reviewed-by: David Baron <[email protected]>
Commit-Queue: Joey Arhar <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1383048}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Nov 14, 2024
This patch makes the <select> element itself handle focus, interaction,
and box decorations instead of the child <button> element. This removes
a lot of complexity, including delegatesFocus, divergent event handling
and button testing, and :-internal-select-has-child-button.

This was discussed here:
w3c/csswg-drafts#10857

Change-Id: Ia036c6dc08be1b86a50bd96239d08ad19c9a7a6b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6001193
Reviewed-by: David Baron <[email protected]>
Commit-Queue: Joey Arhar <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1383048}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Nov 14, 2024
This patch makes the <select> element itself handle focus, interaction,
and box decorations instead of the child <button> element. This removes
a lot of complexity, including delegatesFocus, divergent event handling
and button testing, and :-internal-select-has-child-button.

This was discussed here:
w3c/csswg-drafts#10857

Change-Id: Ia036c6dc08be1b86a50bd96239d08ad19c9a7a6b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6001193
Reviewed-by: David Baron <[email protected]>
Commit-Queue: Joey Arhar <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1383048}
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Nov 16, 2024
…y:contents, a=testonly

Automatic update from web-platform-tests
Make customizable select <button> display:contents

This patch makes the <select> element itself handle focus, interaction,
and box decorations instead of the child <button> element. This removes
a lot of complexity, including delegatesFocus, divergent event handling
and button testing, and :-internal-select-has-child-button.

This was discussed here:
w3c/csswg-drafts#10857

Change-Id: Ia036c6dc08be1b86a50bd96239d08ad19c9a7a6b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6001193
Reviewed-by: David Baron <[email protected]>
Commit-Queue: Joey Arhar <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1383048}

--

wpt-commits: 7a440cb292ea0006c5836a61cfbc35609b973132
wpt-pr: 49161
jamienicol pushed a commit to jamienicol/gecko that referenced this issue Nov 18, 2024
…y:contents, a=testonly

Automatic update from web-platform-tests
Make customizable select <button> display:contents

This patch makes the <select> element itself handle focus, interaction,
and box decorations instead of the child <button> element. This removes
a lot of complexity, including delegatesFocus, divergent event handling
and button testing, and :-internal-select-has-child-button.

This was discussed here:
w3c/csswg-drafts#10857

Change-Id: Ia036c6dc08be1b86a50bd96239d08ad19c9a7a6b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6001193
Reviewed-by: David Baron <[email protected]>
Commit-Queue: Joey Arhar <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1383048}

--

wpt-commits: 7a440cb292ea0006c5836a61cfbc35609b973132
wpt-pr: 49161
@brechtDR
Copy link

I really don't like the button having an all: unset with the latest UA style update. It creates a confusing developer experience as most will expect a button to have certain things, such as a display property set to inline-block, letting you add paddings right away.

@nt1m
Copy link
Member

nt1m commented Nov 18, 2024

I really don't like the button having an all: unset with the latest UA style update. It creates a confusing developer experience as most will expect a button to have certain things, such as a display property set to inline-block, letting you add paddings right away.

Not sure where you see all: unset?

@josepharhar
Copy link
Contributor Author

I really don't like the button having an all: unset with the latest UA style update. It creates a confusing developer experience as most will expect a button to have certain things, such as a display property set to inline-block, letting you add paddings right away.

Not sure where you see all: unset?

I just added it to the issue description. It came out of my code review to add display:contents in chromium. I added a comment explaining why it is needed.

@nt1m
Copy link
Member

nt1m commented Nov 18, 2024

I really don't like the button having an all: unset with the latest UA style update. It creates a confusing developer experience as most will expect a button to have certain things, such as a display property set to inline-block, letting you add paddings right away.

The idea is that select is where you should set your button styles (because that's always how it's been...).

@brechtDR
Copy link

brechtDR commented Nov 19, 2024

I just added it to the issue description. It came out of my code review to add display:contents in chromium. I added a comment explaining why it is needed.

I understand the reason behind it, but I feel like it's "one more caveat" that people will trip over a few times.

for example, a developer might quickly start prototyping something :

select > button { 
  padding: 1cqmin; 
  border: 1px solid #c0ffee; 
}

After doing that, a developer goes to watch the change on the page and wonders why the button doesn't have padding. Looks it up and finds out that he/she needed to add the display property, in contrast to a button anywhere else, where user-agent styles are set to display: inline-block.

That being said, I'm not trying to push on changing this, but I believe it is something we should be aware of when going forward with this. It can potentially be a common pitfall / frustration for developers, especially at first. It's at the least going to bring a small amount of confusion.

@fantasai
Copy link
Collaborator

On the contrary, one of the benefits of select > button { display: contents; } is that it means if you add a <button> inside the select markup, you won't accidentally pick up the generic button { ... } border/background/etc. styles that currently only apply to standalone buttons. And as @nt1m notes, the developer trying to style the button really should be styling the select anyway.

i3roly pushed a commit to i3roly/firefox-dynasty that referenced this issue Nov 20, 2024
…y:contents, a=testonly

Automatic update from web-platform-tests
Make customizable select <button> display:contents

This patch makes the <select> element itself handle focus, interaction,
and box decorations instead of the child <button> element. This removes
a lot of complexity, including delegatesFocus, divergent event handling
and button testing, and :-internal-select-has-child-button.

This was discussed here:
w3c/csswg-drafts#10857

Change-Id: Ia036c6dc08be1b86a50bd96239d08ad19c9a7a6b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6001193
Reviewed-by: David Baron <[email protected]>
Commit-Queue: Joey Arhar <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1383048}

--

wpt-commits: 7a440cb292ea0006c5836a61cfbc35609b973132
wpt-pr: 49161
@josepharhar
Copy link
Contributor Author

I just updated the UA styles again with some changes I worked on with @argyleink mostly to remove small px padding rules and using flex on the select and options to make ::picker-icon and ::checkmark push to edges and easier to use.

@josepharhar
Copy link
Contributor Author

I talked with @nt1m and @fantasai about the proposed styles from my last comment and got some feedback:

  • use margin-inline-start:auto instead of justify-content:space-between to push the ::picker-icon to the right
  • remove the 1px margin at the top of the picker which was used to separate the borders of the picker and the button
  • padding-inline on options and padding-block/padding-inline on button looks good
  • borders of picker and button should be consistent and they should be 1px (picker uses the initial value)
  • border-radius, if we use it, should be in em units instead of px, like 0.25em

I plan on incorporating these into the proposed styles

@css-meeting-bot
Copy link
Member

css-meeting-bot commented Nov 21, 2024

The CSS Working Group just discussed [css-ui] UA stylesheet for appearance:base `<select>` .

The full IRC log of that discussion <gregwhitworth> jarhar: presents presentation
<chrishtr> If you have any questions or feedback about Joey's deck, feel free to post them here and we can discuss async / on the GitHub issue.
<argyle> margin-inline-start instead of justify-content, how come? justify-content will continue to work if authors put checkmarks on the inline-end, where inline-start only works for checkmarks at the start
<emilio> Can we avoid flex / border-radius? The less we change the general layout model the better, IMHO...
<dbaron> fantasai: ...
<dbaron> fantasai: Advantage of background-color is it's something authors will almost always override. IF we do put a background color it's more likely to run into color contrast than if we use a border-radius.
<brecht_dr> q+
<dbaron> fantasai: We should try to make minimal differences. I'd probably go with a or b and not c so there's fewer things to override.
<dbaron> brecht_dr: I agree with ??
<dbaron> brecht_dr: Resetting things gets tedious, fewer things to reset is better.
<masonf> title: foo
<fantasai> Slides for this session: https://lists.w3.org/Archives/Public/www-archive/2024Nov/att-0003/appearance-base-colors.pdf

See Joey's slide deck

Open Questions

  • Should we visually distinguish buttons and inputs somehow?
    • Use border-radius: 0.25em.
    • Use background: color-mix(current-color ...).
    • Use border-radius + background-color.
    • Use neither; keep the styles absolutely minimal.
  • If we distinguish buttons and inputs, which one should select look like?
    • Like buttons.
    • Like inputs.

For the first question, the advantage of using background only is that authors will almost always want to override it anyway, so it rarely needs an extra reset. The disadvantage is that, unlike border-radius, it will impact the color contrast.

@fantasai
Copy link
Collaborator

fantasai commented Nov 21, 2024

Comments on some of the stylesheet details.

  • I think ::picker(select) should be minimally styled and match all other pickers, so probably shouldn't have border-radius.
  • align-content and place-content are redundant, since align-content is a shorthand of place-content.
  • We should have a consistent gap value, not 1em one place and 0.5em in the other. :)

@josepharhar
Copy link
Contributor Author

Thanks for the feedback @fantasai !

From irc:

emilio: Can we avoid flex / border-radius? The less we change the general layout model the better, IMHO...

@emilio Can you elaborate on why using flex is not ideal? I think it greatly improves the ::picker-icon by pushing it to the end of the box. If we don't do that with flex, is there another way to do that?

border-radius I'm going to have a harder time defending, but yeah was an open question about styling buttons in appearance:base.

@tabatkins
Copy link
Member

Yeah, I think using inline-flex is pretty much a necessity here. It is simply the case that inline-block is not sufficient to do any real UI layout; flex is table-stakes for this sort of thing.

border-radius I'm less pressed about.

Use background: color-mix(current-color ...).

By the by, this is an unusable value. The partial transparency means the button background is mostly the underlying background color; if that (an unpredictable value) doesn't contrast with the text, the text becomes unreadable. This only looks reasonable because, in your demos, the underlying background is white, which contrasts with the black text.

What you actually want is color-mix(currentcolor 10%, contrast-color(currentcolor max)) or similar.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

9 participants