
Use plain HTML and CSS to create switch-style accessible checkboxes.
How to use it:
1. Add the role=”switch” attribute to checkboxes and wrap them into respective label elements as follows:
<label> <input type="checkbox" role="switch" disabled> Disabled </label> <label> <input type="checkbox" role="switch" checked> Disabled + Checked </label> <label> <input type="checkbox" role="switch" indeterminate> Indeterminate <script>document.currentScript.previousElementSibling.indeterminate=true</script> </label>
2. The CSS styles to transform the checkboxes into switches.
input[role=switch] {
appearance: none;
-webkit-appearance: none;
position: relative;
display: inline-block;
width: 2.4em;
height: 1.4em;
margin: -.2em 0;
box-sizing: content-box;
padding: 0;
border: none;
border-radius: .7em;
background: rgba(160,160,160,0.7);
box-shadow: 0 .15em .25em rgba(0,0,0,0.5) inset, 0 -.5px 0 rgba(255,255,255,0.2) inset;
transition: background-color 250ms ease, box-shadow 250ms ease;
font-size: 100%;
text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
user-select: none;
outline: none;
}
input[role=switch]::before {
content: '';
display: flex;
align-content: center;
justify-content: center;
position: absolute;
width: 1em;
height: 1em;
left: 0;
top: 0;
background: rgba(240,240,240,0.9);
box-shadow: 0 1px 1px #fff inset, 0 .2em .5em rgba(255,255,255,0.7) inset, 0 -.2em .3em rgba(0,0,0,0.2) inset, 0 .05em .25em rgba(0,0,0,0.7);
border-radius: 50%;
transform: translate(20%, 20%);
transition: transform 250ms ease;
color: rgba(0,0,0,0.3);
line-height: 1;
}
input[role=switch]:focus::before {
background: rgba(255,255,255,0.9);
}
input[role=switch]:checked {
background-color: var(--bg-checked, var(--bg, rgb(60,130,250)));
}
input[role=switch]:focus-visible {
box-shadow: 0 .15em .25em rgba(0,0,0,0.5) inset, 0 -.5px 0 rgba(255,255,255,0.2) inset, 0 0 0 2px rgba(255,255,255,0.8), 0 0 0 4px var(--bg-checked, var(--bg, rgb(60,130,250)));
}
input[role=switch]:checked::before {
transform: translate(120%, 20%);
}
input[role=switch]:indeterminate::before {
transform: translate(70%, 20%);
content: '-';
}
input[role=switch]:disabled:before {
opacity: 0.4;
}






