Pseudo-elements for tracks and thumbs
tl;dr: let's actually do part of
w3c/csswg-drafts#4410
sooner rather than later.
Background
<input
type=range>
was first specced
, with implementations shipping not that
long after. Every implementation has supported the ability for authors
to style the two basic pieces of the range slider (the "track" and the
"thumb"), despite the fact that no spec said how to. We punted on
speccing it at the time in
anticipation of someone robustly defining the
appearance
property. Nobody did so.
w3c/csswg-drafts#4410
proposes to add pseudo-elements for the track and thumb (and more); we
resolved
to do so, everybody wants us to do so, so let's actually do so.
The proposal
We add two new pseudo-elements:
::track
- Represents the track that the thumb moves along.
::thumb
- Represents the thumb that moves along the track.
They work like this:
- Box hierarchy
- the
::track
and::thumb
pseudos are siblings of each other, per@thebabydino
's reasoning inw3c/csswg-drafts#4410
. - Properties which can be set on them
¯\_(ツ)_/¯
Whatever Emilio says they should be. (It'd be nice to support thecontent
property for switch controls; see below.)- Elements that sprout them
<input type=range>
.- (the proposed)
<input type=checkbox switch>
. It has a track and a thumb in its default appearance on all major platforms, so it should share these pseudos with<input type=range>
. - Any future "slider"-like controls should also support these pseudos.
Naming
All engines call these pieces the "track" and the "thumb":
Engine | Track pseudo-element name | Thumb pseudo-element name |
---|---|---|
EdgeHTML | ::-ms-track | ::-ms-thumb |
Gecko | ::-moz-range-track | ::-moz-range-thumb |
WebKit (and Blink) | ::-webkit-slider-runnable-track | ::-webkit-slider-thumb |
"Track" and "thumb" are also the terms used for the analagous parts of scrollbars.
Given the apparent naming consensus, let's skip the bikeshedding and standardize these names.
That's it‽
Yup. Baby steps.
There are
many
more pieces of these controls to also standardize. I look forward
to a world in which web authors reap the rewards of a more holistic
effort at tackling form control styling with
appearance:
base
or whatever, but I'm not trying to do that here.
I'm really just proposing that we finally spec ::track
and ::thumb
pseudos that can be shared by range and
switch controls, and that we not let the (very reasonable) desire for
more to get in the way of this small bit.
Let's not let the perfect be the enemy of the good.
Potential issues
- People may find the name
::track
confusing, given the existence of HTML's<track>
element. I doubt this will prove to be a problem in practice, considering the<track>
element is specific to media and does not create CSS boxes. - People may expect to be able to style scrollbar tracks and thumbs with these pseudo-elements. They can't. I don't think there's much to be done about this.
Future work
After we add ::track
and ::thumb
there's
plenty more to do! w3c/csswg-drafts#4410
and Open
UI have a bunch of ideas that go way beyond these two pseudos.
The two sides of the track
For instance, EdgeHTML also allows you to separately style the bits
of the track on either side of the thumb with
the ::-ms-fill-lower
and ::-ms-fill-upper
pseudos, and Gecko allows you to separately style the lower portion.
The <progress>
and <meter>
elements
also often have a two-part track, and styling them is possible in each
engine, though the mechanisms vary quite a bit from one another.
If we want to make it possible to style the two sections of the track
differently without resorting to appearance: none
, we
should really do so in a way that's consistent across all of these
elements. That might take a while, so let's not
block ::track
and ::thumb
on it.
Circular sliders
This is
a
very cool idea, but I think for now it's okay to leave it to
the appearance:none
escape hatch.
Text inside switches
I don't think this needs to be part of
the
switch MVP, but if
authors want to place text in the thumb or the track of the switch
control, we could simply let them set the content
property on these pseudos (in concert with
:checked
if necessary), e.g.
#power::thumb {
content: "⏻";
}
#power::track {
content: "Off";
}
#power:checked::track {
content: "On";
}