Open zcorpan opened 2 years ago
Is there interest in standardizing this pseudo-class (and make it also available to author CSS)?
cc @mfreed7
Via git blame of WebKit's html.css I found https://bugs.webkit.org/show_bug.cgi?id=220376 -- I think a pseudo-class as suggested here would be less prone to bugs like this (compared to attribute selectors). cc @pxlcoder
Via git blame of Gecko's html.css I found https://bugzilla.mozilla.org/show_bug.cgi?id=1643246 where attribute selectors were replaced with a pseudo-class. cc @emilio @heycam
It certainly seems tricky to select this based on attribute selectors, so I'm supportive of trying to standardize a pseudo class.
Picking a name will be tricky. I'm not sure I like :select-list-box
, since in my view, both in-page and pop-up <select>
s contain a "listbox". One is just a pop-up listbox and the other is an in-page listbox. Perhaps something like :select-pops-up
? Or at least something that refers to the pop-up behavior? Similarly, we need to be careful to distinguish whether this pseudo class refers to whether the listbox pops up or not (as I've assumed), or whether it refers to whether multi-select is supported. Those are (at least theoretically) distinct.
HTML's wording is "list box" for <select multiple>
and "drop-down box" for <select>
. However those terms are not web-exposed anywhere (prior to this pseudo-class), so they can be changed.
I believe the select
element has an aria list box role either way, so that could be confusing.
How about "list box" and "drop-down list box"? (Not sure about "list box" vs "listbox".)
"Drop down" or "drop down list box" seem pretty clear (even though they are "pop up menus" on Mac). But just "list box" by itself is not clear, because I honestly wouldn't remember which one you meant without comparing it to the other term. I think if you had "multiple list box" (or similar*) and "drop down list box" as the two terms, then they'd both be clear, even in isolation.
similar:
List box multiple
Multi-select list box
no-drop list box (clear, but ugh)
It's not necessarily multi-select, though.
<select size=5>
<option>this is still single-select list box
<option>foo
<option>bar
</select>
We could define only a pseudo-class for the drop-down, and rely on the :not()
function to match the not-drop-down state.
select:drop-down-list-box {}
select:not(:drop-down-list-box) {}
+1 to the idea of targeting the idea of having a dropdown. Perhaps something like :has-dropdown
?
@zcorpan works for me. I also like the @dbaron refinement. Though there should probably be another dash, like :has-drop-down
, so we don’t repeat the nowrap mistake.
Also, would a native date picker or color picker be considered a drop-down, like input[type=date]:has-drop-down
?
I’m ambivalent about the extra dash, really.
Also, would a native date picker or color picker be considered a drop-down, like
input[type=date]:has-drop-down
?
Good question. I would say no. The date widgets are not guaranteed to have a drop-down or a popup, it would be conforming to have a control with only spinners, for example. The color well is specified to have a "color picker" that is separate from the color well, but nothing says it has to be a drop-down. Firefox on macOS opens a popup window for the color picker.
Since the need is specific to the select
element, I think we should define it to only apply to select
. Should the naming be different because of that?
A few names to consider
:has-dropdown
:select-has-dropdown
:select-with-dropdown
drop-down
Example usage:
select:has-dropdown { ... }
select:not(:has-dropdown) { ... }
select:select-has-dropdown { ... }
select:not(:select-has-dropdown) { ... }
select:select-with-dropdown { ... }
select:not(:select-with-dropdown) { ... }
or without type selector (when not using :not()
)
:has-dropdown { ... }
select:not(:has-dropdown) { ... }
:select-has-dropdown { ... }
select:not(:select-has-dropdown) { ... }
:select-with-dropdown { ... }
select:not(:select-with-dropdown) { ... }
It is probably better in terms of ergonomics to have two pseudo-classes for the two states, e.g.:
:has-dropdown
and :no-dropdown
:select-has-dropdown
and :select-no-dropdown
:select-with-dropdown
and :select-without-dropdown
Since it will only match select
elements it seems reasonable to include it in the name, as people may expect :has-dropdown
to apply to other things with dropdowns and :no-dropdown
to apply to almost all elements.
It seems to me that if this is only ever going to apply to <select>
, then it should have "select" in the name. Otherwise, this feels confusing:
input[type=date]:has-dropdown { doesn't match, even when the date picker "drop down menu" is present }
As for :has-dropdown
and :no-dropdown
- isn't that exactly why we have :not()
, to avoid the need for that?
I vote for :select-with-dropdown
, because "with" indicates the <select>
comes with a drop-down. Somehow (and I'm not sure why) but :select-has-dropdown
sounds to me like it should apply only when the dropdown is open. Like it currently has a dropdown.
Interesting side reading on "drop-down" vs "dropdown": https://www.chicagomanualofstyle.org/qanda/data/faq/topics/HyphensEnDashesEmDashes/faq0153.html. Perhaps we should use "menu" instead?
I don't think "menu" distinguishes <select>
vs <select size=5>
. The name here is also "for developers", so we're good per the Microsoft Writing Style Guide. :-)
:not()
indeed allows the same expressiveness, but it's a bit more cumbersome compared to using a direct pseudo-class. Compare with
:link { ... }
:visited { ... }
vs
:any-link:not(:visited) { ... }
:visited { ... }
+1 to "put select
in the name" - it means we don't have to figure out whether this also applies to N other things, and verify if new things need to have it, possibly in only certain UAs, etc... Plus the general argument that if it only applies to 1 thing now, people will rely on that fact and use it on its own (without a tagname selector) with the intention of targeting select
s specifically, and that code will then break in the future when we apply it to more. General policy: never use a generic name that could plausibly apply to many things unless there are at least three things that it already applies to.
Relying solely on :not()
for the non-dropdown case is slightly unfortunate, as it requires you to use the tagname in the selector as well - select:not(:select-with-dropdown)
- since just :not(:select-with-dropdown)
will target random elements too. I think we should come up with a name for the other state. I think listbox
is fine - even if it's a little unclear on its own, since it'll be contrasted with dropdown
I think it's reasonable.
Or if we're pretty sure that select
only has two states in this axis (which I think is a safe assumption, given 20+ years of history), :select-with-dropdown
and :select-no-dropdown
might work.
So it sounds like :select-with-dropdown
is the winner for the "with dropdown" state.
For the other state, we have:
:select-no-dropdown
:select-without-dropdown
In https://drafts.csswg.org/indexes/ I see several "no-" but no "without-", so the former seems more CSS-y and is also shorter.
Thus, I suggest we go with :select-with-dropdown
and :select-no-dropdown
.
In https://drafts.csswg.org/indexes/ I see several "no-" but no "without-", so the former seems more CSS-y and is also shorter.
Looking at that list, I see that these no-
properties/values are (mostly) prefixed version of other ones that do not have a prefix. For example no-clip
is the antonym of clip
; not has-clip
or with-clip
.
Working my way back from the suggested select-no-dropdown
, it should go hand in hand with select-dropdown
then?
If select-dropdown
does not make sense, and we do want to keep select-with-dropdown
, its antonym – in similar fashion as clip
/no-clip
– should then become select-no-with-dropdown
? From a linguistic POV the latter doesn’t make sense at all, and it would become select-without-dropdown
.
tl;dr If we have select-with-dropdown
, select-without-dropdown
seems like a better opposite to me.
:select-dropdown
strongly reads as selecting the dropdown itself, so I'd rule that out.
no-with-dropdown
is definitely out, yeah. ^_^
I don't think we need to stick with pure English rules for this; we're not writing a sentence. no-wrap
is similarly slightly awkward if read as normal English; it would be doesnt-wrap
or something if we were shooting for that.
I think sticking with no-dropdown
is fine/preferable, both for its length and its consistency.
Might be good to reuse the well known CSS appearance
values, as vocabulary:
select:menulist
and select:listbox
I think only :listbox
is not great because there are other listboxes other than "<select>
as a listbox" (for example, the dropdown part of a dropdown <select>
is also called a listbox). The appearance
values are also legacy in favor of auto
.
Yeah, and I wouldn't really consider them "well-known" either. I couldn't tell you what appearance
values exist, for example, besides auto
and button
.
I should be able to remotely attend the TPAC CSS meeting either Thursday or Friday, but only before lunch. cc @astearns
Sidenote: If authors had the ability to numerically compare attribute values, they would be able to select those elements using this snippet:
select[size>1],
select[multiple] {
/*🎉 */
}
This, in turn, would make a lovely custom selector as well:
@custom-selector :--with-listbox [size>1], [multiple];
select:--with-listbox {
/*🎉 */
}
@bramus not sufficient for the UA stylesheet, at least, since browsers need to get cases like <select size="+02xyz">
correct.
@astearns is it possible to move this issue to some time before lunch (either Thursday or Friday)?
The CSS Working Group just discussed Pseudo-classes for drop-down vs list box for <select>
.
See https://github.com/whatwg/html/issues/7050
Chromium supports a
:-internal-list-box
pseudo-class in the UA stylesheet, which matches<select>
elements that render as a list box instead of as a dropdown box.Gecko similarly supports
:-moz-select-list-box
in the UA stylesheet.WebKit seems to use attribute selectors instead, although I think it's not entirely accurate since the decision per spec depends on the parsing result of the
size
attribute. (Demo:<select size="+02xyz">
)Web developers could rely on the
multiple
attribute being present to target list boxes, but that might not always work so well, in particular if you're writing CSS that should work for arbitrary HTML.I think it makes sense to add a pseudo-class that matches
select
elements that are list boxes, e.g.:select-list-box
. To match drop-downs, you can doselect:not(:select-list-box)
.Spec: https://drafts.csswg.org/selectors/