Code examples

Speciality stepper integer input

Before using this pattern, consider if using a plain Select dropdown might be more clear and simple for all users. A select does everything that this stepper does, and with less code! Plus, a select is native and accessible out of the box.

This component is useful for small range increments. If the max count is more than 20, consider use of a Text Input field as this component will be cumbersome for people using a mouse.

<div class="stepper">
  <label for="stepper">
  <button class="button minus" aria-label="Decrease Quantity" aria-disabled="true"></button>
  <select id="stepper"
    <option value="1" selected>1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    <option value="4">4</option>
    <option value="5">5</option>
    <option value="6">6</option>
    <option value="7">7</option>
    <option value="8">8</option>
    <option value="9">9</option>
    <option value="10">10</option>
    <option value="11">11</option>
  <button class="button plus" aria-label="Increase Quantity"></button>
  <!-- live container where "Quantity updated, {x}" will be dynamically updated -->
  <div aria-live="polite" class="hidden" id="stepper-status-target"></div>

Developer notes

  • This stepper example provides both button and select elements for users to change a value.

  • A non-visual live container with aria-live="polite" is present in the page at DOM load. When the button elements are activated, this non-visual live container is updated with dynamic content that screen reader users will hear announced as they increment or decrement the value. This dynamic text is then removed from the DOM after a few seconds (but not the actual container with aria-live="polite") so the message is not discovered by screen reader users after interaction. The content of this message dynamically created based on the Label for the Select and the current value of the Select. e.g. “Quantity updated, 4”

  • The value of the select element naturally communicates the updated value to screen reader users so the live container is not updated when that form element is interacted with.

  • The button aria-label values should be plain text and they should include context of what they affect when activated (typically the label for the select). e.g. Increase Quantity, Add Quantity

  • aria-disabled="true" will be applied to the buttons when either end of the range is reached

  • Related alternative patterns: Select dropdown or an ARIA Spinbutton.