Accessible css / js switch
by ian_smithz
HTML
<link rel="stylesheet" href="https://www.screwfix.com/assets/css/sfx.min.css">
<br> <br>
<label class="check-switch" for="switch_1">
<input id="switch_1" type="checkbox">
<span aria-hidden="true"></span>
</label>
<!-- Some screen reader combinations reported to be buggy with role="switch" - you can just use checkbox version -->
<!--
<label class="check-switch" for="switch_2">
<input id="switch_2" data-check-switch="" role="switch" type="checkbox">
<span aria-hidden="true"></span>
</label>
-->
CSS
/* containing label */
.check-switch {
padding: .5em;
margin: 0 3em;
position: relative;
}
/* using the before/after pseudo elements of the span to create the "switch" */
.check-switch span:before,
.check-switch span:after {
border: 1px solid #565656;
content: "";
position: absolute;
top: 50%;
transform: translateY(-50%);
}
/* styling specific to the knob of the switch */
.check-switch span:after {
background: #fff;
border-radius: 100%;
height: 1.5em;
right: 1.5em;
transition: right .1825s ease-in-out;
width: 1.5em;
}
/* styling specific to the knob "container" */
.check-switch span:before {
background: #eee;
border-radius: 1.75em;
height: 1.75em;
right: .25em;
transition: background .2s ease-in-out;
width: 2.75em;
}
/* hide the actual checkbox from view, but not from keyboards or ATs.
Instead of standard visually hidden styling, instead set opacity to
almost 0 (not zero for ChomeVox legacy bug), pointer-events none, and
then set to full height/width of container element so that VO focus
ring outlines the component, instead of a tiny box within the component
*/
.check-switch input {
height: 100%;
left: 0;
opacity: .0001;
position: absolute;
top: 0;
width: 100%;
}
.check-switch input:not([role="button"]) {
pointer-events: none;
}
.check-switch input:focus + span:before {
/*outline: #a9a9a9 dotted 2px;
outline-offset: 1px;*/
outline: 0;
-webkit-box-shadow: 0 0 0 2px rgba(2,117,216,.25);
box-shadow: 0 0 0 2px rgba(2,117,216,.25);
}
/* change the position of the knob to indicate it has been checked*/
.check-switch input:checked + span:after {
right: .25em;
}
/* update the color of the "container" to further visually indicate state */
.check-switch input:checked + span:before {
background: #2196f3;
}
/* 'color in' the switch knob in high contrast mode by giving it
a large border */
@media screen and (-ms-high-contrast: active) {
.check-switch span:after {
background-color: windowText;
}
}