Customized spinbuttons

Summary

Principle

Spinbuttons are form elements that allow the user to set a numeric value. They are presented as a text field associated with two buttons used to increase or decrease the value of the field by one increment.

Spinbuttons which are “customized” are not built using the standard HTML code as found in the specification <input type="number" />, but by a text field which is associated with the two images, icon fonts or specific styles, to show the increase and decrease “buttons”.

The following code shows how to reproduce the behavior of HTML spinbuttons, when the native spinbuttons cannot be used.

This code is based on the “Spinbutton” design pattern found in the ARIA Authoring Practices Guide (APG) of the W3C.

Core HTML base

<p id="label">Spinbutton label</p>
<div>
<input type="text" role="spinbutton" aria-valumin="0" aria-valuemax="10" aria-valuenow="8" aria-labelledby="label" />
<img aria-hidden="true" src="plus.png" alt="+" />
<img aria-hidden="true" src="minus.png" alt="-" />
</div>

ARIA roles, states and properties

  • role="spinbutton" must be applied to the spinbutton.
  • The aria-valuemin attribute must be applied to the spinbutton. Its value must be set to the minimum value allowed for the spinbutton.
  • The aria-valuemax attribute must be applied to the spinbutton. Its value must be set to the maximum value allowed for the spinbutton.
  • The aria-valuenow attribute must be applied to the spinbutton. Its value must be set dynamically to that of the spinbutton.
  • The spinbutton must be programmatically associated with its label using aria-labelledby:
    • The spinbutton label must have an id attribute set to a unique value.
    • The spinbutton must have the aria-labelledby attribute set to the value of the id of the label of the spinbutton.
  • The aria-hidden="true" attribute must be added to each image that simulates an increase or decrease button.

Keyboard interaction

Keyboard interaction is the same as for classic HTML spinbuttons.

Tab

When the user tabs to the spinbutton, the focus is placed in the text field. When the focus is in the text field pressing the Tab key allows the user to leave the spinbutton.

Shift + Tab

This key combination has the same behavior as the Tab key but in the reverse order.

Up arrow

When the focus is on the text field, this key increases the value of the text field one step.

Down arrow

When the focus is on the text field, this key decreases the value of the text field one step.

Home

When the focus is on the text field, this key increases the value of the text field to its maximum.

End

When the focus is on the text field, this key decreases the value of the text field to its minimum.

Expected behavior

  • The keyboard focus remains on the text field during the use of the spinbutton, and remains there until the Tab key is pressed.
  • When the focus is on the text field, the value of the spinbutton can be modified by typing values on the keyboard or by using the Up arrow, Down arrow, Home and End.
  • The increase and decrease buttons are not keyboard focusable, but can be operated with a mouse.
  • The value of the aria-valuenow attribute must be updated dynamically so that it is always identical to the value of the spinbutton.
  • The value of the spinbutton cannot be greater than the aria-valuemax attribute.
  • The value of the spinbutton cannot be less than the aria-valuemin attribute.

11 comments

  • Par Brian, le 12 February 2019 at 6h59.

    Ce commentaire a été publié sur une ancienne version des notices AcceDe Web. Il se peut que son contenu ne soit plus d'actualité.

    By removing type=number, touch browsers won’t open/switch keyboards to number pad. Is there a technique both this method and correct type=number can both be used?

    Cheers!

    Répondre

    • Par David Monnehay, le 13 February 2019 at 10h30.

      Ce commentaire a été publié sur une ancienne version des notices AcceDe Web. Il se peut que son contenu ne soit plus d'actualité.

      Hello Brian,

      Using a type="number" would result in an actual spin button (and therefore work perfectly with assistive technologies without any aria attributes). The goal of this article is to explain how to simulate a spinbutton using a input type="text" and ARIA attributes, if for some reason an input type="number" could not be used. But using a native HTML tag or attribute, like type="number" in this case, would always be a better option if possible.

      Répondre

  • Par Camille, le 1 September 2022 at 15h13.

    Hello,

    Currently I use the INPUT HTML object with the SpinButton role, with which I launch a JavaScript function when I detect the onChange event.

    The problem is that the onChange event is too general, and I will need to distinguish if the change is due to the user clicking the top arrow of the spinButton, or if they clicked the bottom arrow of the spinButton. What are the events that make it possible to identify these two actions separately?

    Thanks in advance.

    Répondre

    • Par Jimmy Burbure, le 5 September 2022 at 9h18.

      Hello,

      Sorry, but without seeing the full code of your component, we can’t answer your question.
      Can you please elaborate on your question a bit more?

      Regards,
      Jimmy.

      Répondre

  • Par Camille, le 5 September 2022 at 15h40.

    Hello,

    This is the code i am using :

    INPUT role=spinbutton aria-valuemax=500 aria-valuemin=0 aria-valuenow=1 type=number value=0 onchange=”montant(W, X, Y, Z);” name=nb_cde

    Currently I use the INPUT HTML object with the SpinButton role.

    montant(X,Y,Z) is a JavaScript function which is lauched when I detect the onChange event.

    The problem is that the onChange event is too general, and I need to distinguish if the change is due to the user clicking the top arrow of the spinButton, or if the user clicked the bottom arrow of the spinButton. What are the events that make it possible to identify these two actions separately?

    Thanks in advance.

    Répondre

    • Par Jimmy Burbure, le 5 September 2022 at 15h58.

      Camille,

      The easiest way to do this would be to add a “+” and “-” button around the field (with an id on each) and then listen for JavaScript click events on these elements.

      Regards,
      Jimmy.

      Répondre

  • Par Camille, le 7 September 2022 at 9h25.

    Hi Jimmy,

    It is quite complicate to add a “+” and “-” button around the field, because i have 400 fileds like this in my page.

    Is there any easiest way ?

    Thank you very much.

    Best regards
    Camille

    Répondre

    • Par Jimmy Burbure, le 8 September 2022 at 9h53.

      Hello Camille,

      To my knowledge, no, sorry.
      I don’t think I can help you any further in your case, it’s more of a development issue than an accessibility issue.
      You can always ask your question on Stack Overflow and keep us informed of the answer!

      Have a nice day.
      Jimmy.

      Répondre

  • Par Camille, le 8 September 2022 at 19h22.

    Thank you Jimmy. I posted on Stack Overflow. I will keep you informed if any answer.

    Répondre

  • Par Camille, le 9 September 2022 at 16h12.

    Hi Jimmy,

    Someone helped me to solve the problem on Stack Overflow :

    I added jQuery in the javascrit code :

    if ($(nomzone1).data(‘old-value’) < $(nomzone1).val()) { alert('Alert up');}
    else { alert('Alert down');}
    $(nomzone1).data('old-value', $(nomzone1).val());

    It works perfectly. Thank you again.

    Have a nice day.
    Camille

    Répondre

    • Par Jimmy Burbure, le 9 September 2022 at 16h36.

      I’m glad to hear it !
      Have a nice day too.
      Jimmy.

      Répondre

Add a comment

All fields are mandatory.

Back to top