4

I am currently working on a website which incorporates heavily styled inputs, for example using the <label>-element to style checkboxes:

<label class="checkbox">
  <input type="checkbox">
  <span></span>
</label>

And where the standard <input> types just can't be reliably styled, We have recreated the neccessary functionality with other element types, for example <input type="range"> has been replaced with the following (and a bit of javascript):

<div class="rangeinput">
  <div class="rangeinput-thumb></div>
  <div class="rangeinput-slider"></div>
</div>

Now, the question is how to semantically add labels to these elements.

For regular inputs the <label>-element would work, but for the provided examples neither <label> nor <div> are allowed content of a <label>.

The checkbox-case can be solved by assigning an id to the checkbox and using the for-attribute of the label element, so that it does not have to be placed around the other label. But this does not work for any custom elements since they are not labelable, and it would be preferable to use a single solution for every input.

Currently I am wrapping every input-like element in a <fieldset> with a <legend>, but this feels more like a hack than actually helping semantics:

<fieldset>
  <legend>A styled rangeinput:</legend>
  <div class="rangeinput">
    <div class="rangeinput-thumb></div>
    <div class="rangeinput-slider"></div>
  </div>
</fieldset>

This question is not about the click-to-focus effect of the element, but rather how to semantically associate a short, descriptive text with an element that takes a user input.

Jave
  • 31,598
  • 14
  • 77
  • 90

1 Answers1

3

I would propose the aria-describedby attribute for this. You can then place your descriptive text in virtually any element, even if it's visually hidden.

The aria-describedby attribute is not limited to form controls. It can also be used to associate static text with widgets, groups of elements, regions that have a heading, definitions, and more. The aria-describedby attribute can be used with semantic HTML elements and with elements that have an ARIA role.

You might also (or instead) use aria-labelledby to give your control a more formal label. See Is it ok to combine aria-label and aria-describedby?

Yet another option is simply the aria-label attribute, which could be placed on the outer widget element. This is an always-hidden option for assistive tech usage only.

In your case, you might do something like this (with more specific wording than I've provided):

<div id="rangeLabel">Value Selector</div>

<div class="rangeinput" aria-describedby="rangeDesc" aria-labelledby="rangeLabel">
  <div class="rangeinput-thumb"></div>
  <div class="rangeinput-slider"></div>
</div>

<div id="rangeDesc">Use the range slider to set a value.</div>

Do keep in mind that if your range slider itself isn't accessible, this is all rather moot. It should be keyboard-controllable and have good audible feedback when used with screen readers, etc.

isherwood
  • 58,414
  • 16
  • 114
  • 157