skip to Main Content

In an HTML form (being generated by React, but that’s not relevant), I have a checkbox with a label. The checkbox is hidden (invisible), and the way to check/uncheck it is by clicking the label. At the moment, I have the tabindex set so that the label comes into focus after the previous form control. However, I can’t find a way to let the user check/uncheck the checkbox using only the keyboard, even though the label is in focus. Does anyone have any idea how to do this? Basically I want there to be a way to achieve using only the keyboard what would usually be done by clicking the label with your mouse – checking/unchecking the checkbox.

Here is the basic idea of the code I’m using:

Note: I’ve added a small js snippet to log the state of the checkbox to the console whenever the checkbox is changed.

document.getElementById("hidden-checkbox").onchange = function () {
    console.log(document.getElementById("hidden-checkbox").checked);
}
#hidden-checkbox {
    display: none;

    /* Could also use:
    position: absolute;
    clip: rect(1px, 1px, 1px, 1px);
    padding: 0;
    border: 0;
    height: 1px;
    width: 1px;
    overflow: hidden;
    */
}
<div class="fields">
    <input type="text" id="other-field" tabindex="1">
    <input type="text" id="other-field-2" tabindex="2">
    <input type="checkbox" id="hidden-checkbox" tabindex="-1">
    <label id="label" for="hidden-checkbox" tabindex="3">Click this to toggle!</label>
</div>

2

Answers


  1. You could keep going as you did with your concept of removing the actual checkbox from tab order and make the label focusable at its place, but be aware that:

    • You don’t get the check/uncheck with spacebar or enter key behavior for free. You have to implement it yourself.
    • You must use ARIA on the label to indicate to screen readers that it’s a checkbox and its state, otherwise screen reader users won’t know about it

    However, you you could do much simpler by letting the checkbox be normally focusable. Spacebar and enter will work without the need for you to do anything special.
    Screen reader users will find it and will be able to check it as usual. To them, it will just "look" like a normal checkbox. No ARIA is needed.

    Since the actual checkbox is invisible on the screen, you can use some CSS or js to indicate the checked state to the user and when it has the focus.
    You are certainly already doing it at least for the state, so it shouldn’t be a big deal.

    Login or Signup to reply.
  2. You don’t need to fuss around with tabIndex or anything. When a label is associated with a checkbox, mouse clicking on the label is the same as clicking on the checkbox. How do you still make the checkbox available to keyboard-only and screen reader users, even after you hide it? By hiding it visually.

    If you make the checkbox have a height/width of 0, it won’t appear visually, but is still available when you tab around or look for checkboxes. Like this:

    #hidden-checkbox{
     height: 0;
     width: 0;
     margin: 0;
     padding: 0;
    }
    

    If you want to see it in action, here’s a pure CSS solution:
    https://codepen.io/chart2music/pen/OJojagX

    Side note –

    Your use case doesn’t need tabIndex at all, anywhere. Input fields will receive tab focus automatically, so not only do you not need to add the tabIndex attribute, you’re likely to create a weird and unpredictable tab order. Here’s your rule of thumb for when to use it:

    • If an element DOES receive focus, but you want it NOT to, use tabIndex=-1
    • If an element DOESN’T receive focus, but you want it TO, use tabIndex=0
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search