Apple have just released Safari Technology Preview 17.4, which introduces a new addition to checkboxes: The switch
-attribute:
<input type="checkbox" switch>
<input type="checkbox" switch checked>
In all it's glory, this is what you get with the above markup:
It's still early days, because when you zoom in, you get this funky result:
Interestingly enough, it's not using system colors for the un-checked state, but for the checked state, it's using AccentColor
.
In dark mode, weirdly enough, it doesn't use AccentColor
.
It would be much more consistent, if the system colors ButtonFace
and AccentColor
were used for the two states, no matter what the color-scheme
is.
NOTE: At the moment, Safari is actually the only browser that supports the system color
AccentColor
.
Under the Hood
Inspecting the control reveals an aspect-ratio
of 1.8/1
and a relative height of approx. 1.1em
, so a super-simple fallback could be:
<input type="checkbox" role="switch">
[role=switch] {
appearance: none;
aspect-ratio: 1.8/1;
background: #ddd;
border-radius: 1em;
display: grid;
height: 1.1em;
margin: 0;
padding: 0.0625em;
&::after {
background: #fff;
border-radius: 50%;
content: '';
width: 1em;
}
&:checked {
background: #16f;
justify-content: end;
}
}
Using grid here, you can control the border with padding
and scale it to any size, by updating font-size
:
If you want to fine-control the various parts better, add some CSS custom properties:
[role=switch] {
--_bg: #DEDEDE;
--_bga: #FFF;
appearance: none;
aspect-ratio: 1.8/1;
background: var(--_bg);
border-radius: 1em;
display: grid;
height: 1.1em;
margin: 0;
&::after {
background: var(--_bga);
border-radius: 50%;
border: 0.046875em solid color-mix(in srgb, var(--_bg) 95%, #000);
content: '';
display: block;
height: 1.00625em;
width: 1.00625em;
}
&:checked {
--_bg: #0f83ff;
justify-content: end;
}
}
And if you really want to simulate Apple's switch, dive into box-shadow
, as they're using very subtle box-shadows for both parts of the switch!
It will be interesting to see, if switch
will make it into the standard, and if other browsers will adopt it.
Otherwise, stick with role="switch"
for now.
Top comments (0)