In Safari 17.4, the WebKit team at Apple
shipped a native HTML switch element.
The core idea is that an <input type="checkbox"> can progressively be enhanced
to become a switch by adding the switch attribute. Browsers that don't support
the switch attribute will just silently ignore it and render the switch as a
regular checkbox. At the time of this writing, Safari version 17.4 and later is
the only browser to support the new switch element natively. This blog post
introduces a polyfill that brings almost native support to browsers that
lack it.
The markup below shows you how you use the switch element. If your browser
doesn't support the element natively and you view this page on my blog directly
(that is, not in your feed reader), the polyfill should have already kicked in
and you should see two switch controls below the code sample: one regular
switch, and one with a red
accent-color.
<label>Toggle me <input type="checkbox" switch checked /></label>
<style>
.special {
accent-color: red;
}
</style>
<label
>Toggle me, I'm special <input type="checkbox" switch checked class="special"
/></label>
Accessibility
If a checkbox becomes a switch, the browser automatically applies the
ARIA switch
role. This role is functionally identical to the checkbox role, except that
instead of representing "checked" and "unchecked" states, which are fairly
generic in meaning, the switch role represents the states "on" and "off". The
polyfill does this for you.
When your users have the
prefers-contrast
setting enabled to convey that they prefer more contrast, the polyfill adds more
visible borders. Some operating systems like Windows or browsers like Firefox
additionally support a high contrast mode. The polyfill also has support for
that.
The macOS operating system additionally has an accessibility setting to Differentiate without color, which causes switch controls to get rendered with additional visual on/off indicators. Since there is currently no direct CSS media query for this specific preference, I opted to display these indicators whenever a high-contrast preference is detected, ensuring maximum clarity for those who need it.
A common accessibility challenge with switches identified in research (that predates the HTML switch control) is an uncertainty whether the user should tap or slide the switch to change its state. The polyfill, like the native counterpart in Safari, supports both. Another challenge is whether the label "on" indicates the current state of the switch or the resulting state after interacting with it. I personally think smartphones—most notably the iPhone—have taught people how to use switches, but I still recommend you do your own usability research before adding a switch to your site.
Internationalization, and styling
The polyfill supports the various
writing-mode
options, like "vertical-lr".
It's also aware of the directionality of text via the
dir
attribute.
Status in HTML
The switch element was proposed to be included in HTML in Issue #4180 filed in November 2018. PR #9546 (opened in July 2023) proposed a fix and was approved by Anne van Kesteren in August 2023. At the time of this writing, the PR to the HTML spec is still open, with concerns from several stakeholders, including from Google.
I am not and was not part of the standardization discussion around the element,
I just personally like the progressive enhancement pattern that reminds me of
the pattern used in
customizable <select> elements
that in the case of non-support just get rendered as regular selects.
Get the polyfill
You can
get the polyfill from npm
and find the code on GitHub.
The
README
has detailed usage instructions that I won't repeat here, including important
tips on how to avoid FOUC (Flash of Unstyled Content). You can also play with
a demo of the polyfill that
shows off more features of the polyfill, like all the various writing modes, and
the different ways to style the switch. And with that: happy switching!
This post appeared first on https://blog.tomayac.com/2026/01/12/a-polyfill-for-the-html-switch-element/.



















