Design system Inputs

Stepper

Increment or decrement one small bounded count. The group owns the border; each end keeps the full target.

.mk-stepper

Overview

The stepper changes one small bounded count — adults, children, nights. The group owns the border, each end keeps a full 44px target, and the value sits centred in tabular numerals so it does not shiver between 1 and 11. Try it.

2

Usage

  • Adjust a small bounded countUse a stepper for integer values with a meaningful minimum, maximum, and step of one.
  • Make incremental changes faster than typingMinus and plus change the visible value immediately and become unavailable at their respective bounds.
  • Use Text input for broad numeric entryAmounts, measurements, and values with large or irregular ranges should be typed and validated instead of stepped.

Anatomy

1
2
2 3 4
  1. 1The group. One border around the whole control — the boundary is the component's, not each button's. Hover and focus-within warm it.
  2. 2Minus control. A 44 × 44px button with no invisible expander: its visible seat is already the full target.
  3. 3The value. Centred, tabular numerals, stable width — the number the two ends argue about.
  4. 4Plus control. The matching 44 × 44px button increments the value. It has the same visible target and focus treatment as Minus.

Variants and states

One size — the 44px control height. A count that needs a denser face belongs to a different control.

States

Every state below is the real component wearing that state, not a picture of it.

StateSpecimenWhat changes
Rest
2
The strong grey edge on the group.
Hover
2
The group border warms — the family's shared answer — and the end under the pointer takes the quiet band wash.
Keyboard focus
2
The standard 2px camel outline, drawn inward on the focused end; focus-within warms the group border the same way hover does.
At a bound
0
The blocked end takes aria-disabled and stays where it is. It never disappears: a vanished minus teaches nothing about why the count stops here.

Do and don't

Do

The field label names the count; the ends name it too, for the screen reader.

Don't

A bare number input for a three-step count trades two honest presses for a keyboard, spinners the UA draws its own way, and free text to validate.

Copy

  • The ends say the objectThe accessible names are "Fewer adults" and "More adults" — not bare arithmetic.
  • The bound explains itself nearbyWhy two is the floor is the row's sentence, not the control's.

Accessibility

  • Real buttons at the endsEach has its own object-naming label.
  • The value is announcedA live region speaks the new count after each press.
  • Blocked, not removedaria-disabled at the bounds keeps the end reachable and its reason learnable.

When to reach for something else

  • An unbounded or large numberUse a numeric Text input — forty presses are not an interface.
  • Choosing from named optionsUse Dropdown; a stepper's value has no names.

Markup

<div class="mk-stepper">
  <button class="mk-stepper-btn" type="button" aria-label="Fewer adults">−</button>
  <span class="mk-stepper-value">2</span>
  <button class="mk-stepper-btn" type="button" aria-label="More adults">+</button>
</div>