Number Field
Numeric input with increment and decrement stepper controls. Supports min/max constraints, step value, arrow key increments, and format display for currency and percent values.
Anatomy
- 1 Format prefix/suffix — optional currency (
$) or percent (%) indicator - 2 Input primitive — numeric text entry element (value or placeholder)
- 3 Stepper controls — decrement and increment buttons
Options
States
Format display
Table of options
| Property | Values | Default |
|---|---|---|
| value | number | — |
| min | number | — |
| max | number | — |
| step | number | 1 |
| format | none / currency / percent | none |
| placeholder | text | 0 |
| disabled | true / false | false |
| state | default / hover / active / focus / disabled / readonly / invalid | default |
Behaviors
Stepper buttons
Minus and plus buttons increment or decrement the value by the configured step amount. JavaScript enhancement via input-field.js handles click events.
Min/max constraints
The min and max attributes constrain the accepted range. The stepper clamps to these bounds. Arrow key increments also respect constraints.
Custom step
The step attribute controls the increment amount for both button clicks and arrow key presses. Fractional steps are supported.
Currency format
The format="currency" option prepends a $ symbol as a decorative, non-interactive prefix. For localised currency formatting, provide the symbol via the prefix slot.
Percent format
The format="percent" option appends a % symbol as a decorative suffix after the input.
Disabled state
A disabled number field cannot be edited or stepped. It is removed from the tab order and stepper buttons are visually hidden.
Usage guidelines
Always pair with a label
<label for="qty">Quantity</label>
Do
Every number field must have a visible label, aria-label, or aria-labelledby.
Don't
Do not render a number field without an associated label or accessible name.
Use min/max to communicate range
Do
Set min and max to prevent out-of-range entries and constrain stepper buttons.
Don't
Avoid displaying a percent field without min="0" max="100" constraints.
Code
HTML
<!-- Plain number field -->
<div class="uif-input-field uif-number-field">
<input class="uif-input" type="number" placeholder="0" value="0" />
<span class="uif-input-field-control">
<button type="button" aria-label="Decrease value"><!-- minus icon --></button>
<button type="button" aria-label="Increase value"><!-- plus icon --></button>
</span>
</div>
<!-- Currency format -->
<div class="uif-input-field uif-number-field">
<span class="uif-number-field-prefix" aria-hidden="true">$</span>
<input class="uif-input" type="number" placeholder="0" value="9.99" step="0.01" />
<span class="uif-input-field-control">
<button type="button" aria-label="Decrease value"><!-- minus icon --></button>
<button type="button" aria-label="Increase value"><!-- plus icon --></button>
</span>
</div>
<!-- Percent format -->
<div class="uif-input-field uif-number-field">
<input class="uif-input" type="number" placeholder="0" value="75" min="0" max="100" />
<span class="uif-number-field-suffix" aria-hidden="true">%</span>
<span class="uif-input-field-control">
<button type="button" aria-label="Decrease value"><!-- minus icon --></button>
<button type="button" aria-label="Increase value"><!-- plus icon --></button>
</span>
</div>
Web Component
<uif-number-field value="0" step="1" aria-label="Quantity"></uif-number-field>
<uif-number-field format="currency" value="9.99" step="0.01" aria-label="Price"></uif-number-field>
<uif-number-field format="percent" value="75" min="0" max="100" aria-label="Progress"></uif-number-field>
Nunjucks macro
<div class="uif-input-field uif-number-field"><input class="uif-input" type="number" placeholder="0" value="0" step="1" /><span class="uif-input-field-control">
<button type="button" aria-label="Decrease value"><span class="uif-icon" style="--uif-icon-src: url('/assets/icons/minus-circled.svg');" aria-hidden="true"></span></button>
<button type="button" aria-label="Increase value"><span class="uif-icon" style="--uif-icon-src: url('/assets/icons/plus-circled.svg');" aria-hidden="true"></span></button>
</span>
</div>
<div class="uif-input-field uif-number-field"><span class="uif-number-field-prefix" aria-hidden="true">$</span><input class="uif-input" type="number" placeholder="0" value="9.99" step="0.01" /><span class="uif-input-field-control">
<button type="button" aria-label="Decrease value"><span class="uif-icon" style="--uif-icon-src: url('/assets/icons/minus-circled.svg');" aria-hidden="true"></span></button>
<button type="button" aria-label="Increase value"><span class="uif-icon" style="--uif-icon-src: url('/assets/icons/plus-circled.svg');" aria-hidden="true"></span></button>
</span>
</div>
<div class="uif-input-field uif-number-field"><input class="uif-input" type="number" placeholder="0" value="75" min="0" max="100" /><span class="uif-number-field-suffix" aria-hidden="true">%</span><span class="uif-input-field-control">
<button type="button" aria-label="Decrease value"><span class="uif-icon" style="--uif-icon-src: url('/assets/icons/minus-circled.svg');" aria-hidden="true"></span></button>
<button type="button" aria-label="Increase value"><span class="uif-icon" style="--uif-icon-src: url('/assets/icons/plus-circled.svg');" aria-hidden="true"></span></button>
</span>
</div>
Accessibility
- The
<input type="number">element is natively keyboard accessible: arrow keys increment or decrement by the configured step,Home/Endjump to min/max. - Stepper buttons have descriptive
aria-labelvalues ("Decrease value"/"Increase value"). - Format prefix and suffix elements carry
aria-hidden="true"to avoid duplicate announcements; the accessible label or surrounding<label>should convey the unit context. - Disabled fields are removed from the tab order via the native
disabledattribute.