Code examples

Semantic HTML

While there is a native range input, it is difficult to style reliably across browsers.

This is one of the exceedingly rare instances where a custom element makes a lot of sense.

<div class="range-group">
  <input tabindex="-1" 
          value="10" 
          aria-hidden="true"
          class="range-value" 
          id="cowbellValue">
  <div>
    <label for="cowbell">
      How much cowbell?
    </label>
    <input type="range"
      id="cowbell"
      name="cowbell"
      min="0"
      max="11"
      value="10"
      step="1">
  </div>
</div>

Custom elements

This is a rare instance where custom elements are easier to style reliably across browsers.

<div id="range-label">
  How much cowbell?
</div>
<div class="track">
  <div id="thumb"
       role="slider"
       tabindex="0"
       aria-valuemin="0"
       aria-valuenow="10"
       aria-valuemax="11"
       aria-labelledby="range-label">
  </div>
</div>

Working example: https://www.w3.org/TR/wai-aria-practices/examples/slider/slider-1.html

Developer notes

Name

  • Include for="input-id in each <label> label to associate it with the input
  • Use aria-label="Input name" as a last resort if a <label> can’t be used
  • Don’t hide the label on focus

Role

  • Identifies as a text input

State

For custom elements, use these aria attributes to describe the min, max and current value.

  • aria-valuemin
  • aria-valuemax
  • aria-valuenow

Group

  • Include for="input-id in each <label> label to associate it with the input

Focus

  • Focus must be visible