5

I develop a mobile web app and I am testing it for accessibility. I have come across some checkboxes that can't be checked when using TalkBack on Android (with "Explore by Touch" enabled) or VoiceOver on iOS.

The issue is that we "hide" the actual checkbox and the user sees and interacts with a styled label that looks and acts like a checkbox.

This is part of the CSS that hides the actual checkbox:

.input-tick {
    position: absolute;
    left: -999em;

Here is the full HTML and CSS example (See also on JSFiddle.)

.input-tick {
  position: absolute;
  left: -999em;
}
.input-tick[disabled] + label {
  cursor: not-allowed;
  opacity: 0.5;
}
.input-tick[type="checkbox"]:checked + label::after {
  border: 3px solid;
  border-right: none;
  border-top: none;
  content: "";
  height: 10px;
  left: 4px;
  position: absolute;
  top: 4px;
  width: 14px;
  transform: rotate(-55deg);
}
.input-tick[type="radio"] + label::before {
  border-radius: 100%;
}
.input-tick + label {
  cursor: pointer;
  font-size: 14px;
  margin-bottom: 0;
  position: relative;
}
.input-tick + label::before {
  border: 2px solid #000;
  content: "";
  display: inline-block;
  height: 22px;
  margin-right: 0.5em;
  vertical-align: -6px;
  width: 22px;
}
.input-tick + label:not(.checkbox):not(.block-label) {
  display: inline-block;
}
.center {
  text-align: center;
}
<div class="center">
  <input type="checkbox" class="input-tick" id="agree-to-terms" name="agree-to-terms">
  <label for="agree-to-terms">
    I agree
  </label>
</div>

TalkBack and VoiceOver try to outline both the hidden checkbox and the label:

TalkBack Screenshot

When VoiceOver and TalkBack try to "click" the checkbox, the x and y coordinates of the click are in the middle of the box that is trying to outline the checkbox and the label. This click is outside of the label for the checkbox, so the checkbox doesn't get checked.

Is there a way to get VoiceOver and TalkBack to only deal with the label? Any other way to fix this?

cramill
  • 106
  • 1
  • 7

2 Answers2

4

I think I may have found a solution to this issue. After looking at other ways to do a styled checkbox, I found that many suggest to use display: none or visibility: hidden, but it sounds like this removes some functionality of the checkboxes (being able to tab to focus them and spacebar to toggle).

But there is another way to hide the checkbox. Instead of this:

.input-tick {
    position: absolute;
    left: -999em;
}

We can do this:

.input-tick {
    position: absolute;
    opacity: 0;
    z-index: -1;
}

Found over here: https://stackoverflow.com/a/32876109/3014407

Since the styled checkbox is bigger than the actual checkbox, the actual checkbox is not visible. This produces the expected result when using TalkBack or VoiceOver:

TalkBack Screenshot

Community
  • 1
  • 1
cramill
  • 106
  • 1
  • 7
0

You might consider using the checkbox aria role on a custom element and define the aria-checked attribute dynamically with javascript

<div id="customcheckbox" tabindex="0" aria-role="checkbox"
     class="checked" aria-checke="true">This is checked</div>

... becomes ...

<div id="customcheckbox" tabindex="0" aria-role="checkbox"
     class="unchecked" aria-checke="false">This is not checked</div>
Adam
  • 17,838
  • 32
  • 54
  • I still need the actual checkboxes for forms that get submitted, does this act like an input when inside of a form? – cramill Apr 28 '16 at 23:35
  • No, but you perfectly can use a totally hidden field (display:none or input[type=hidden]) with that solution without having a focusable but not visible active element (which is an accessibility problem for keyboard-only users) – Adam Apr 29 '16 at 07:07
  • It's a good idea, but I'd rather not add in JavaScript to check/uncheck things when it can all be done with HTML and CSS. My fix is just two lines of CSS. – cramill Apr 29 '16 at 14:54