Open josepharhar opened 7 months ago
My gut feeling on this is don't bother providing a check by default at all. Instead just provide UA styles of the following (or something similar). This way the default is usable but it's ultimately up to the authors to make it nicer. Because I feel like adding a checkmark is just going to create more work for ourselves making a good way to style it (which will mostly just be removing it)?
option:checked {
color: selecteditemtext;
background-color: selecteditem;
}
Rendered:
Happy to make a new issue for this but seeing as it's slightly related.
selectlist {
accent-color: blue;
}
Does not seem to impact on any of the default UA styles (e.g hover state)
Should it?
adding a checkmark is just going to create more work for ourselves making a good way to style it
Agreed, in the OP I almost said "I have so many questions that I don't feel like this can be completed before we finish single select and move on to multi select". If this isn't absolutely necessary from an accessibility point of view, then maybe we could save this for multi select.
Does not seem to impact on any of the default UA styles (e.g hover state)
Are these things already stylable via other CSS properties?
I created accent-color so that you could change the color of fully native form control elements like <input type=checkbox>
which cannot be styled any other way.
Yeah they can be styled by doing option:hovered
option:focus-visible
etc so it's not big deal. Just might be something that comes up from people who do
* {
accent-color: var(--my-very-execellent-color);
}
so the pro of a checkmark marker for the default selected state is that it provides an overt visual "YOU CHOSE THIS" confirmation without having to have a strong (dark) default selected option background color - which if the decision ends up being to not have selection follow focus, we need to then have a strong focus indicator vs the strong background color. The checkmark loosens that a bit so the focus indicator could be a strong background color and then the selected state could be exactly the same as the unselected state - save for the 'checkmark' that appears.
the con then being that if no one wants that checkmark / if conflicts with people being able to identify a multiselect vs single select popup, then there's little in the way of default UA styling to fall back on for authors who just didn't want that default checkmark style - and they have to roll their own selected state and focus state.
keep in mind, that we do also need to consider how these selected vs unselected styles need to translate to windows high contrast mode - and since so many colors are kicked to the curb, a checkmark becomes another easy win for denoting the selected state vs the unselected state in that limited coloring scenario.
the above may make it seem like i'm advocating for the checkmark, but i'm personally a bit indifferent about it. it's just sorta factually beneficial to have it as a default UA style for ticking as many a11y boxes as possible for the default. These boxes can be ticked in other ways, it just means different things visual treatments need to be implemented/considered.
also i did not mean to make any sort of pun with talking about checkmarks and 'ticking boxes' and yet here we are. please clap.
One potential issue with the checkmark is if you copy the option to <selectedoption>
is it gonna copy with the checkmark?
At least on macOS this isn't the behaviour of select nor would it be what I expect?
not if it's a css marker specific to the option element and not selectedoption
The Open UI Community Group just discussed selectlist: Should the "checked" option have a checkmark next to it?
.
https://jsfiddle.net/cdygvmeb/23/ - Excuse the awful CSS but this kinda shows my thoughts on hey I want custom markers.
Just display none the marker pseudo put your SVG in the option and control it based on :checked
pseudo class.
I just discovered that the existing ::marker
pseudo has a really limited set of properties: https://developer.mozilla.org/en-US/docs/Web/CSS/::marker#allowable_properties . I suspect some developers would want to animate transform / opacity
For a more extreme animation example, have a look at the material checkbox animation: https://material-components.github.io/material-components-web-catalog/#/component/checkbox . This would probably require a custom component.
My gut is that that's probably fine? As they can just do what I mentioned above and get the full capabilities? The reason checkboxes specifically are such a pain is exactly because they don't have full HTML abilities?
It's also worth being aware I think there's dicussion on making :marker less restricted for the details styleability but I may be mistaken with that.
My gut is that that's probably fine? As they can just do what I mentioned above and get the full capabilities? The reason checkboxes specifically are such a pain is exactly because they don't have full HTML abilities?
+1. It seems like the basic use case is "just" to have a visible checkmark next to the selected option. That's all you get currently on Mac platforms:
That's not a "checkbox" at all, it's just a "checkmark" which can be achieved (assuming we go this route) via
selectlist option:checked::marker {
content: "✓"
}
I think that achieves 80+% of the use cases. You can pick your own marker, you can style it appropriately, etc.
For the 20% of use cases where you want more control, you're more on your own. But you can, e.g. use SVGs instead of just content
via Luke's approach. Or if you want full interactive <input type=checkbox>
's inside the options, first, you're running afoul of https://github.com/openui/open-ui/issues/540#issuecomment-1212330487. But if you manage to make that accessible somehow, you can use a similar technique of adding the checkboxes to your options, and hooking them up correctly via JS.
Yeah. Whatever can be done to make people NOT put a checkbox inside of something that already represents means of selecting a choice would be super great. This sort of misunderstanding happens far too often.
@scottaohara @mfreed7, to be clear I wasn't suggesting it is a checkbox or should have a checkbox put in it, but I could imagine developers wanting similar animations to the material checkbox checkmark animation, especially for the multi-select use case.
it was clear, sorry if my response made you think otherwise!
@scottaohara @mfreed7, to be clear I wasn't suggesting it is a checkbox or should have a checkbox put in it, but I could imagine developers wanting similar animations to the material checkbox checkmark animation, especially for the multi-select use case.
Yep understood! I just wanted to carefully make the distinction between checkmark and checkbox, since in the live discussion it felt a bit muddled. Maybe just to me.
when design treats checkmark and checkbox the same, it gets super muddled.
that screenshot is from fluent ui - where in the past that widget was incorrectly coded as checkboxes inside of options because "they look like checkboxes". it has since been fixed so that these are just visual checkboxes to represent the selected state of the option, but i get questions on a bi-weekly basis if "this is ok" because it "looks like" a checkbox but doesnt behave like one.
Right, agreed! Thanks for the example. I think this is good reason to make it easy to make something that visually looks like a checkbox as the marker so that there's an easy path which is semantically correct 🙂
So should we just have a user-agent style rule that looks like this? The visibility:hidden
would add padding so the actual content of the options is still rendered at the same horizontal alignment.
selectlist option::marker {
content: '✓';
}
selectlist option:not(:checked)::marker {
visibility: hidden;
}
We could also use an svg or something instead of content
, but that would be harder to add styling to - which might be good or bad, I'm not sure yet. It depends on whether we want to encourage people to display:none
the ::marker
in order to style it or not. The styling of this I think is related to https://github.com/openui/open-ui/issues/881
Also, this rule would probably not apply to options which are slotted in from outside the selectlist, which is something we probably want to support: https://github.com/openui/open-ui/issues/565
i like the visibility: hidden idea for the consistent padding
definitely would want that default UA style for the checkmark to be the following so we don't get an announcement of a "checkmark" along with the selected state.
selectlist option::marker {
content: '✓' / '';
}
There hasn't been any discussion on this issue for a while, so we're marking it as stale. If you choose to kick off the discussion again, we'll remove the 'stale' label.
I threw together a work in progress patch to add checkmarks next to selected options by adding this to the UA stylesheet:
select option::before {
content: '';
display: inline-block;
inline-size: 1.4em;
block-size: 1.0em;
background-image: url(data:image/svg+xml,%3Csvg%20width%3D%2220%22%20height%3D%2220%22%20fill%3D%22none%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cpath%20d%3D%22m8.229%2014.062-3.521-3.541L5.75%209.479l2.479%202.459%206.021-6L15.292%207l-7.063%207.062Z%22%20fill%3D%22%23000%22%2F%3E%3C%2Fsvg%3E);
background-origin: content-box;
background-repeat: no-repeat;
background-size: cover;
}
select option:not(:checked)::before {
visibility: hidden;
}
Here is a screenshot of what it looks like:
You can opt-out of it with option::before { display:none; }
.
I feel like using ::before
won't make it through the standards and maybe we would have to switch to ::marker
or create a new pseudo-element, but is this what yall would like? Would having this by default get in the way of anything? Are there any improvements to the style rules I wrote that yall can think of?
the downside to using a graphic as the default is that it becomes more difficult to make sure this will stay visible if someone turns on a dark high contrast theme. If it was a unicode character, it could just automatically update to the default color for whatever high contrast theme was chosen. Similarly, if someone just wanted to make the dropdown have a dark background (a dark mode, or just a dark ui website in general) they'd have to replace the graphic - instead of just doing something like color: #fff
.
again, not against the graphic approach - but it will require more default work (for browser implementation and author overwriting).
I figure we should match the down arrow in the default button and use an svg, and I think that using a unicode character might have other issues. We can use light-dark() to make the checkmark white instead of black, and I believe there is a separate stylesheet for high contrast mode where we can also choose white or black.
if someone just wanted to make the dropdown have a dark background (a dark mode, or just a dark ui website in general) they'd have to replace the graphic - instead of just doing something like color: #fff.
I see... it would be cool if we could make the svg know what color its painted on or what its computed background-color is and respond accordingly, but I don't know if that svg technology exists.
Note that this is why I noted when I proposed a new need for a checkbox
element it was due to none of these solutions actually meeting the needs devs have for simplistic style adjustments. I cover this quite in-depth in this older proposal for an indicator pseudo:
Effectively, to @josepharhar point if a UA wants to have them in the non-standardized scenario and handle the a11y that comes with that (whether it being swapping sheets, etc) then that is fine but I don't think we should do this in the default styles for select. So possibly we raise this to the agenda to resolve on whether we want that as a default style or not?
I'd much prefer something like https://github.com/openui/open-ui/issues/863#issuecomment-1765107097 (along with using the correct alt syntax with content attribute)
The fonts might change how it's rendered but I think that's probably fine. base appearance is mostly about stylability rather than everything being 100% identical (though we should aim to get as close to that as possible). But it's much much easier for styling. It just works with the color property. forced-colors (Windows' Contrast themes) mode can choose to just remove it entirely should it wish too.
I cover this quite in-depth in this older proposal for an indicator pseudo
Very nice! Yeah this has a lot of similarities with the checkbox we are talking about here
I don't think we should do this in the default styles for select
Why not? Your indicator proposal seemed to suggest that we should in fact use an svg instead of a unicode character.
The fonts might change how it's rendered but I think that's probably fine. base appearance is mostly about stylability rather than everything being 100% identical (though we should aim to get as close to that as possible). But it's much much easier for styling. It just works with the color property. forced-colors (Windows' Contrast themes) mode can choose to just remove it entirely should it wish too.
If the unicode character is more stylable then that's a good reason. I'm not sure if I could replace the svg background-url with a full on svg element in the dom unless I add it to the option element's UA shadowroot, which currently doesn't contain anything and just slots in all content.
For single select, I don't think the checked option should have a checkmark next to it by default.
My question is -- is it an accessibility issue to add this checkbox via a background image and pseudo element content? This is how I imagine most would do it
I'm actually in favor of adding the checkmark, via ::marker
or content:'✔️'
. I've heard several times (would be great to get confirmation here) that it's an accessibility issue to only distinguish the selected vs. unselected options via color change. Having an explicit checkmark helps people who can't distinguish the colors. If that's true, I'd rather it be (just a bit!) of work for developers to remove the checkmark if they don't want it.
As a side-benefit, if we get this styling right, it'll feed naturally into the multi-select of the future, which needs checkmarks.
This adds complexity in terms of design and UA style standardization
Yeah it will be hard to standardize this, but it will also be hard to standardize the other hundreds of lines of css.
While this is a relatively common UI, it's not in the majority of selects. In my research, I've found one in about 20-25% of custom selects. This means users will need to "undo" the style frequently
I'd rather it be (just a bit!) of work for developers to remove the checkmark if they don't want it.
Yeah I'm hoping that it will just be option::bikeshed { display:none; }
which would be pretty simple to turn off the checkmark
The Open UI Community Group just discussed selectlist: Should the "checked" option have a checkmark next to it?
.
I touched on this while discussing https://github.com/openui/open-ui/issues/827
In order to indicate the currently selected option inside the listbox (I supposed it should also already be indicated in the button), should the currently selected/checked option in a single select selectlist have a checkbox rendered next to it?
For multi select, we would of course need this. For single select, maybe not?
The MacOS native select picker has a checkmark to the left of the selected option and also renders on top of the button which would otherwise indicate what the selected option is. The aria practices single select example has a checkmark to the right of the option: https://www.w3.org/WAI/ARIA/apg/patterns/combobox/examples/combobox-select-only/
If we did this, how would it be implemented? Just a user-agent style thats like
option:checked::after { content: '✓' }
? Or perhaps a new pseudo-element like::checkmark
? Should it be an SVG? Or be some sort of native checkbox thing? Should it be to the right of the option like the aria-practices example? Or should it be on the left? If it's on the left, should there be padding there for every option?Whatever the case is, I feel like this should be easy for the developer to override/replace/remove, right @una? Would the
content
property inoption:checked::after { content: '✓' }
be easy enough to override? Should there be an easy way to move it from the left side of the option to the right side or vice versa?@scottaohara @smhigley