C-37 · Components · Editor (Office)
All elements · SpinButton on the Components page
Last checked 2026-10-22 · Awaiting approval · Accessibility tests
Approve SpinButton
Approving as
Guidance
When to use
- Use it for a numeric value with a unit in the office editors, such as indent, spacing, scale or column width.
-
Use
data-size="sm"(the default) in the ribbon anddata-size="md"in dialogs. - Use it when users both type exact values and nudge them in steps.
-
Show the unit in
__unitand say it in full inaria-valuetext, such as "1.27 centimeters".
When to consider something else
- When the exact number matters less than a quick visual adjustment, such as zoom or transparency, use a Slider. See Slider.
- For a number in a record form outside the editors, use a Text field with numeric input. See TextField.
- When the value comes from a short fixed list, use a Select. See Select.
Usability
-
Set
aria-valueminandaria-valuemaxto the real limits and clamp typed values to them. -
Accept typed values in the shown unit, and keep
aria-valuenowandaria-valuetextin sync. - Name the step buttons after the field, such as "Increase indent left".
- Use Fluent Regular chevrons for the steps inside
.qf-office(README, Icons).
- Don't hide the unit, or put it only in the placeholder.
- Don't put the step buttons in the tab order; the keyboard steps from the field.
- Don't reject an out-of-range entry silently; clamp it or show an error the user can read.
Accessibility
Keyboard
| Keys | Action |
|---|---|
| Tab | Moves focus to the field; the step buttons are skipped. |
| Arrow Up / Arrow Down | The binding must increase or decrease the value by one step. |
| Page Up / Page Down | The binding must increase or decrease the value by a large step. |
| Home / End | The binding should set the minimum or maximum value when both are defined. |
| Arrow Left / Arrow Right | Move the caret in the field; the ribbon toolbar does not take them from a text input. |
| Enter | The binding must commit a typed value. |
Roles and names
-
__inputhasrole="spinbutton", anaria-label,aria-valuenow,aria-valuemin,aria-valuemaxandaria-valuetextwith the full unit word. -
__unitisaria-hidden, becausearia-valuetextalready says the unit. -
__upand__downare buttons withtabindex="-1"and names such as "Increase scale".
Focus
-
The whole control shows the focus ring through
:focus-withinwhile the field has focus. - Clicking a step button must leave focus in the field.
Other requirements
- The step buttons are 1rem wide and half the field height, below 2.5.8's 24px; typing and the arrow keys are the equivalent, so the field itself must stay at least 24px high.
- The
smfield is 1.5rem (24px) high andmdis 2rem. - In forced colors the border becomes CanvasText.
-
If a value fails validation, describe the error in text and link it with
aria-describedby(3.3.1).
Test your implementation too. This guidance covers the element as specified here. How a screen composes it (labels, order, announcements) still needs its own keyboard and screen reader check.
Accessibility tests
Passed the gate (run 358b316 on 2026-10-22): no finding in any theme. Awaiting a person’s approval of the checklist below.
| Area | Automated | A person checks |
|---|---|---|
| General | Passed | Color is never the only cue, text alternatives say the same thing as the graphic, and the element reads the same in the light and the dark theme. |
| Zoom | Passed | At 200% zoom, at 320 CSS pixels wide and with the WCAG text-spacing overrides, nothing is lost, clipped or overlapping. |
| Keyboard | Passed | Every row of the Keyboard table works, focus is always visible and never trapped, and the tab order follows the reading order. (6 rows) |
| Screen reader | Passed | With NVDA or JAWS on Windows and VoiceOver on macOS, names, roles and states are announced as Roles and names says, and changes are announced once. (3 items) |
Approving. When the checklist passes on the checked run, record it with
bun run a11y:approve -- spin-button --by "Your name" and commit
a11y/approvals.json with the rebuilt pages.
All test status
Package
Consumers link one stylesheet, css/classic/index.css, which includes every element. The
files below are where this element is defined.
Latest updates
No recorded changes yet.