w3c / csswg-drafts

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

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

Open josepharhar opened 1 month ago

josepharhar commented 1 month ago

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.

select {
  border: 1px solid currentColor;
  background-color: color-mix(in lab, currentColor 10%, transparent);
  color: inherit;
  font: inherit;
  padding: 0.25em .5em;
  text-box: trim-both;

  border-radius: 0.25em;
  display: inline-block;
  box-sizing: border-box;
  min-block-size: max(24px, 1.2em);
  min-inline-size: 24px;
  white-space: normal;
}

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::picker(select) {
  box-sizing: border-box;
  overflow: auto;
  border: 1px solid rgba(0, 0, 0, 0.15);
  border-radius: 0.25em;
  padding-block: 0.25em;
  padding-inline: 0;
  background-color: Field;
  margin: 0;
  inset: auto;
  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 {
  min-inline-size: 24px;
  min-block-size: 24px;
  align-content: center;
  display: block;
  padding-block-start: 0;
  padding-block-end: 1px;
  padding-inline: 2px;
  white-space: nowrap;
}

select option:hover {
  background-color: SelectedItem;
  color: SelectedItemText;
}

select option::check {
  content: '\2713' / '';
}
select option:not(:checked)::check {
  visibility: hidden;
}

select::select-arrow {
  padding-inline-start: 0.5em;
  display: block;
  content: counter(fake-counter-name, disclosure-open);
}

select optgroup {
  padding-inline: 2px;
  font-weight: bolder;
}

select optgroup option {
  padding-inline-start: 20px;
  font-weight: normal;
}
nt1m commented 1 month ago

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 commented 1 month ago

Some feedback:

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 commented 1 month ago

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 https://github.com/w3c/csswg-drafts/issues/10866#issuecomment-2350130260.

  • 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 commented 1 month ago

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 commented 1 month ago

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 commented 1 month ago

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 commented 1 month ago

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 commented 1 month ago

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 commented 1 month ago

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

css-meeting-bot commented 1 month ago

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

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 commented 1 month ago

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 commented 1 month ago

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