ARIA: spinbutton role
The spinbutton role defines a type of range that expects the user to select a value from among discrete choices.
Description
The spinbutton role indicates that the element is an input widget that restricts its value to a set or range of discrete values. The role also comes with increment and decrement functionality. For example, in a widget that enables users to choose an amount to bet in a game of Texas Holdem, the spinbutton role can allow users to select a number between the minimum and maximum bets in increments, as allowed by the current game rules.
The spinbutton represents the range of possible values. The value of the spinbutton input represents the current value.
Spinbuttons often have three components, including a text field that displays the current value, an increment button, and a decrement button. The text field is usually the only focusable component because the increment and decrement functions are keyboard accessible via arrow keys. Typically, the text field also allows users to directly edit the value.
In addition to including the tabindex attribute to enable spinbutton focus, keyboard and pointer device support must be implemented. Directional keys such as the arrow keys must be supported for keyboard users. Changing the value when increment and decrement buttons are clicked must be supported for pointing devices. See keyboard interactions below.
[!NOTE] It is recommended to use
<input type="number">element, or other input types for dates and time that also implicitly have therole="spinbutton"semantic, rather than thespinbuttonrole. User agents provide stylized widget for the these input elements which provide default increment, decrement, and native range limiting functionality. When using non-semantic elements, all features of the native semantic element need to be recreated with ARIA attributes, JavaScript, and CSS.
ARIA range widget options
ARIA provides developers with six different range widget roles, including progressbar, meter, slider, and spinbutton.
The progressbar role, similar to HTML’s {{HTMLElement('progress')}} element, is a read-only range. It indicates the portion of completion of a task, progressing in a single direction, such as a file upload’s loading progress bar that eventually reaches 100% when fully loaded.
The meter role, similar to HTML’s {{HTMLElement('meter')}} element, is a read-only gauge. It indicates the amount of something within a known range, such as a computer’s battery indicator or a car’s gas gauge.
The slider role, similar to HTML’s input of type range, <input type="range">, is a read-write input range. Sliders allow users to select a value between the predefined minimum and maximum values. The user selects a value by moving a slider thumb along a horizontal or vertical slider to select a value.
While all three of these ranges have the same ARIA states and properties, the spinbutton role is the only read-write range: it is the only one whose value changes via user interaction. As such, it must be able to receive focus. In addition, keyboard interaction, mouse clicks, and touch interaction must be supported.
[!WARNING] To change the spinbutton value, touch-based assistive technologies need to respond to user gestures for increasing and decreasing the value by synthesizing key events. Fully test spinbutton widgets using assistive technologies on devices where touch is a primary input mechanism before using the
spinbuttonrole (and all range widgets).
Common attributes
The aria-valuemin attribute sets the minimum value. If omitted or not a number, it defaults to 0 (zero).
The aria-valuemax attribute defines the maximum value. If it is missing or not a number, it defaults to 100.
The aria-valuenow attribute value must be between the minimum and maximum values, both inclusive. This attribute is required for spinbutton and meter, and optional for progressbar.
For spinbutton, unless using semantic HTML elements like <input type="number">, if the value is updated, the aria-valuenow value must also be updated programmatically.
The optional aria-valuetext attribute is included when the aria-valuenow numeric value doesn’t reflect the intended value of the spinbutton. The optional minimum, maximum, and current values should be numeric. When the values these numbers represent are not numeric, the aria-valuetext attribute should be included with a string value defining the numeric value. For example, if using a spinbutton for t-shirt sizes, the aria-valuetext attribute should shift from XX-Small through XX-Large as the aria-valuenow increases.
The aria-valuetext value must be updated as the value or aria-valuenow is updated. ARIA attributes are supported on semantic HTML elements. While there is no equivalent HTML attribute for <input>, you can include aria-valuetext on any {{htmlelement('input')}} type. When aria-valuetext is an important feature for a spinbutton, consider using {{HTMLElement('select')}} with {{HTMLElement('option')}} elements instead.
An accessible name is required. If the spinbutton role is applied to an HTML {{HTMLElement('input')}} element, the accessible name can come from the associated {{HTMLElement('label')}} . Otherwise, use aria-labelledby if a visible label is present or aria-label if a visible label is not present.
When not using the HTML {{HTMLElement('input')}} element to create your spinbutton, include the tabindex attribute to make the spinbutton focusable. The spinbutton role is user-interactive, and therefore, requires being able to receive focus. Focus should be placed on the spinbutton input and not on the associated buttons that increment and decrement the spinbutton value.
Descendants limited to buttons or text
There are some types of user interface components that, when represented in a platform accessibility API, can only contain specific content. The children or owned elements of spinbutton are limited to a textbox and two buttons. Alternatively, the spinbutton role can be applied to a text input and sibling buttons can be used to support the increment and decrement functions.
Associated WAI-ARIA roles, states, and properties
-
aria-valuenow(required)- : Set to a decimal value between
aria-valueminandaria-valuemax, indicating the current value of the spinbutton. If not present, there is no default value.
- : Set to a decimal value between
-
- : Assistive technologies often present the value of
aria-valuenowas a number. Ifaria-valuenowcannot be accurate, usearia-valuetextto provide the spinbutton with a more understandable value.
- : Assistive technologies often present the value of
-
- : Set to a decimal value representing the minimum value and less than
aria-valuemax. If not present, there is no default value.
- : Set to a decimal value representing the minimum value and less than
-
- : Set to a decimal value representing the maximum value and greater than
aria-valuemin. If not present, there is no default value.
- : Set to a decimal value representing the maximum value and greater than
-
- : Defines the string value or identifies the element (or elements) that label the spinbutton element providing an accessible name. An accessible name is required.
-
- : Defines a string value that labels the spinbutton element. This provides an accessible name to the element when no visible label is available to provide the required accessible name via
{{HTMLElement('label')}}oraria-labelledby.
- : Defines a string value that labels the spinbutton element. This provides an accessible name to the element when no visible label is available to provide the required accessible name via
Keyboard interactions
| Key(s) | Action |
|---|---|
| Right and Up arrows | Increase the selected value by one step |
| Left and Down arrows | Decrease the selected value by one step |
| Page Up | (Optional) Increase the value by a set amount greater than or equal to one step |
| Page Down | (Optional) Decrease the value by a set amount greater than or equal to one step |
| Home | Set the spinbutton to the minimum value |
| End | Set the spinbutton to the maximum value |
For the optional Page Up and Page Down keys, the change in spinbutton value should preferably be by an amount larger than the step changes made by Up and Down arrow keys.
Examples
In the example below, a spinbutton role has been defined to allow users to select a day of the month.
<p id="day">Enter the day of the month</p>
<button type="button" tabindex="-1" aria-label="previous day">˱</button>
<div
role="spinbutton"
tabindex="0"
aria-valuenow="1"
aria-valuetext="first"
aria-valuemin="1"
aria-valuemax="31"
aria-labelledby="day">
1
</div>
<button type="button" tabindex="-1" aria-label="next day">˲</button>
In this example, we included a negative tabindex to remove the buttons from the default tabbing order. We also added tabindex to a normally non-interactive {{HTMLElement('div')}} to add the spinbutton itself to the tabbing order. This example requires JavaScript to handle keyboard actions when the spinbutton has focus and when a mouse user clicks on the buttons.
With semantic HTML
This could have also been written using semantic HTML, removing the need for any CSS or JavaScript and also removing the need to include and provide functionality for extraneous incrementing and decrementing buttons. The code snippet below shows the previous example without the spinbutton role and using semantic HTML.
<label for="day">Enter the day of the month</label>
<input
type="number"
value="1"
aria-valuetext="first"
min="1"
max="31"
id="day" />
{{EmbedLiveSample("With_semantic_HTML", 50, 50)}}
In this case, the only JavaScript needed would be to update the aria-valuetext when the input value changes, which really is an optional feature in this case.
Best practices
HTML’s <input type="number"> implicitly has the role of spinbutton. HTML’s <input type="date"> has 3 nested spin buttons, one each for month, day, and year. When using semantic HTML form elements for their intended purposes, do not use aria-valuemax or aria-valuemin attributes; use min and max instead. Otherwise, any global aria-* attributes and any other aria-* attributes are applicable to the spinbutton role.
Prefer semantic HTML
It is recommended to use the native {{HTMLElement("input")}} element of type number, <input type="number">, rather than the spinbutton role.
Specifications
{{Specifications}}
See also
<input type="number"><input type="date"><input type="time">- Other range widgets include:
meterscrollbarseparator(if focusable)progressbarslider
- Working examples: