I have a custom checkbox toggle that I am using and it's working great on click, the problem is I also want it to be accessible with a keyboard but I can't figure out how to make it focusable. I've tried adding tabindex="1"
to the label and adding :focus-visible
CSS to it, but I can't seem to tab into it to toggle it on/off with the enter key.
const toggle = document.querySelector('.toggle-input');
toggle.addEventListener('change', function() {
console.log(toggle.checked);
});
.instruction {
font-size:20px;
font-weight:bold;
font-family:sans-serif;
}
.toggle {
position: relative;
display: inline-block;
width: 100px;
margin: 100px 0 0;
padding: 4px;
border-radius: 40px;
}
.toggle:focus-visible {
outline: red dotted 2px!important;
outline-offset: 2px;
}
.toggle:before,
.toggle:after {
content: "";
display: table;
}
.toggle:after {
clear: both;
}
.toggle-bg {
position: absolute;
top: -4px;
left: -4px;
width: 100%;
height: 100%;
background-color: #C0E6F6;
border-radius: 40px;
border: 4px solid #81C0D5;
transition: all 0.1s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.toggle-input {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: 1px solid red;
border-radius: 40px;
z-index: 2;
opacity: 0;
}
.toggle-switch {
position: relative;
width: 40px;
height: 40px;
margin-left: 50px;
background-color: #F5EB42;
border: 4px solid #E4C74D;
border-radius: 50%;
transition: all 0.1s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.toggle-input:checked ~ .toggle-switch {
margin-left: 0;
border-color: #DEE1C5;
background-color: #FFFDF2;
}
.toggle-input:checked ~ .toggle-bg {
background-color: #484848;
border-color: #202020;
}
.toggle-input:checked ~ .toggle-switch .toggle-switch-figure {
margin-left: 40px;
opacity: 0;
transform: scale(0.1);
}
.toggle-input:checked ~ .toggle-switch .toggle-switch-figureAlt {
transform: scale(1);
}
<div class="instruction">Click here and then tab into toggle</div>
<label class="toggle" tabindex="1">
<input class="toggle-input" type="checkbox" />
<div class="toggle-bg"></div>
<div class="toggle-switch"></div>
</label>
You should have a look at here
Warning: You are recommended to only use 0 and -1 as tabindex values. Avoid using tabindex values greater than 0 and CSS properties that can change the order of focusable HTML elements (Ordering flex items). Doing so makes it difficult for people who rely on using keyboard for navigation or assistive technology to navigate and operate page content. Instead, write the document with the elements in a logical sequence.
const label = document.querySelector(".toggle");
const toggle = document.querySelector(".toggle-input");
toggle.addEventListener("change", function() {
console.log(toggle.checked);
});
label.addEventListener("keydown", (e) => {
e.preventDefault(); // disables default behavior - if you remove this, you can switch the toggle using Space key too
if (e.key === "Enter") {
if (toggle.checked) {
toggle.checked = false;
} else {
toggle.checked = true;
}
}
});
.instruction {
font-size: 20px;
font-weight: bold;
font-family: sans-serif;
}
.toggle {
position: relative;
display: inline-block;
width: 100px;
margin: 100px 0 0;
padding: 4px;
border-radius: 40px;
}
.toggle:focus-visible {
outline: red dotted 2px !important;
outline-offset: 2px;
}
.toggle:before,
.toggle:after {
content: "";
display: table;
}
.toggle:after {
clear: both;
}
.toggle-bg {
position: absolute;
top: -4px;
left: -4px;
width: 100%;
height: 100%;
background-color: #c0e6f6;
border-radius: 40px;
border: 4px solid #81c0d5;
transition: all 0.1s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.toggle-input {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: 1px solid red;
border-radius: 40px;
z-index: 2;
opacity: 0;
}
.toggle-switch {
position: relative;
width: 40px;
height: 40px;
margin-left: 50px;
background-color: #f5eb42;
border: 4px solid #e4c74d;
border-radius: 50%;
transition: all 0.1s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.toggle-input:checked~.toggle-switch {
margin-left: 0;
border-color: #dee1c5;
background-color: #fffdf2;
}
.toggle-input:checked~.toggle-bg {
background-color: #484848;
border-color: #202020;
}
.toggle-input:checked~.toggle-switch .toggle-switch-figure {
margin-left: 40px;
opacity: 0;
transform: scale(0.1);
}
.toggle-input:checked~.toggle-switch .toggle-switch-figureAlt {
transform: scale(1);
}
<div class="instruction">Click here and then tab into toggle</div>
<label class="toggle" tabindex="0">
<input class="toggle-input" type="checkbox" />
<div class="toggle-bg"></div>
<div class="toggle-switch"></div>
</label>