数字输入与步进器系统 是做什么的?
目的
数字输入与步进器系统提供了一个标准化的框架,用于设计、构建和实现用于选择、调整或输入离散数值的控件。精确的数字输入——例如购物车商品数量、SaaS 座位分配、定价层级单位、预算范围或尺寸规格——需要平衡快速微调与直接文本编辑、明确的上下限边界状态、适合触摸的点击目标以及完整的键盘/屏幕阅读器无障碍支持。
标准的 HTML <input type="number"> 控件在不同浏览器中渲染不一致,通常带有微小且不可自定义的原生微调箭头,违反了触摸目标指南(WCAG 2.2 SC 2.5.8)并触发意外滚动调整。本技能定义了自定义数字步进器和带单位字段的明确 UI 模式、空间布局规则、交互状态和无障碍标准。
使用场景
- 电商购物车数量选择器: 让购物者能够轻松地在商品详情页、购物车抽屉和结账汇总表中增加、减少或输入商品数量。
- SaaS 计划席位与许可证控件: 在定价页面或订阅管理设置中配置用户席位、服务器实例或存储容量(GB)。
- 带单位的表单输入: 捕获受约束的指标,如百分比值(0–100%)、年龄限制、物品尺寸(长/宽/高)或货币金额。
- 财务与计算器控件: 在交互式计算器中选择贷款期限、存款金额或投资增量。
- 仪表盘与筛选控件: 在数据密集的桌面环境中调整数值阈值、分页行数限制或指标范围筛选器。
何时不使用
- 连续范围选择: 对于非特定数值范围探索,精确值不如相对位置重要时,请使用
accessible-range-slider-implementation或双滑块控件。 - 任意大数字: 对于输入信用卡号、电话号码、邮政编码或社保号,增减操作毫无意义,请使用标准
<input type="text" inputmode="numeric">配合form-design-system。 - 日期与时间选择: 选择日历日期、月份或时钟时间时,请使用
calendar-and-date-system。 - 大型离散选项集: 在预配置的批量数量(例如 25、50、100、500)中进行选择时,请使用
segmented-control-system或custom-select-and-combobox-system。
输入
- 值边界: 最小值(
min)、最大值(max)和步进增量(step)约束。 - 上下文与密度: 可用的布局空间(紧凑的内联表格行 vs. 突出的商品详情页购买区块)。
- 输入格式与单位: 相关的物理或货币单位(例如
$、%、items、kg、seats)。 - 交互模式: 是否允许直接手动文本输入,或者调整仅限于步进器按钮。
- 品牌与表面令牌: 用于表面背景、活动边框、禁用状态、焦点环和图标字形的调色板令牌。
输出
- 步进器组件规范: 定义减少按钮、数字显示/输入、增加按钮和单位标签的可视化结构。
- 边界与状态矩阵: 默认、悬停、焦点、禁用(在最小/最大值限制)、加载和错误状态的可视化处理。
- 响应式空间布局规范: 跨断点的触摸目标尺寸(触摸至少 44x44px,紧凑桌面为 24x24px)、间距和字体度量。
- 无障碍与键盘映射: ARIA 属性(
role="spinbutton"、aria-valuenow、aria-valuemin、aria-valuemax)、实时区域配置和键盘快捷键处理程序规范。
工作流
1. 选择步进器变体
根据上下文和交互意图选择合适的结构变体:
- 标准水平步进器(三段式分割): 左侧是减少按钮(
-),中间是文本输入,右侧是增加按钮(+)。最适合电商商品详情页、购物车项和 SaaS 座位计数器。 - 紧凑内联步进器(堆叠箭头): 文本输入,尾部有垂直堆叠的微按钮。最适合高密度桌面数据表、工具栏和 SaaS 设置侧边栏面板。
- 带单位输入框: 带有固定前缀/后缀单位标签(例如
$、USD、px、%)和可选步进器按钮的文本字段。最适合金融输入和系统配置表单。 - 独立按钮计数器: 完全可点击的药丸状按钮,点击后打开内联模态框/弹出框,或在获得焦点时变为活动步进器。
2. 建立视觉结构和触摸目标规则
使用清晰的几何参数构建组件:
- 触摸目标尺寸: 确保所有可交互的增加/减少按钮在移动端/触摸界面上至少具有 44x44px 的最小点击目标(WCAG 2.5.5 / 2.5.8)。在仅桌面的紧凑 UI 上,至少保持 24x24px 并带有足够的点击填充。
- 输入字段尺寸: 使用 CSS
ch单位根据预期的最大数字位数动态设置宽度(例如,对于 2 位数字的数量,width: calc(3ch + 2rem))。 - 排版与对齐: 数值在输入字段内居中对齐。使用等宽数字(
font-variant-numeric: tabular-nums;)以防止在快速值变化期间发生布局偏移。 - 视觉分组: 将按钮和输入框封闭在共享的边框容器或连续的分割药丸内,以表示统一的功能。
3. 定义边界行为和禁用状态
清晰传达最小和最大限制,避免用户困惑:
- 在最小边界处(
value <= min):- 禁用减少按钮(
disabled属性和aria-disabled="true")。 - 应用低对比度禁用样式(例如
opacity: 0.4; cursor: not-allowed;)。 - 如果在电商购物车上下文中
min === 1,当值为 1 时,可选择将减少按钮转换为“删除”图标,以允许删除行项目。
- 禁用减少按钮(
- 在最大边界处(
value >= max):- 禁用增加按钮(
disabled属性和aria-disabled="true")。 - 如果用户尝试进一步增加,提供内联帮助文本(例如“每单最多 10 件”)或微妙的工具提示。
- 禁用增加按钮(
- 直接输入验证:
- 在输入框
blur事件上,自动将超出边界的输入值钳制到最近的有效限制(例如,在最大值为 10 的字段中输入99则钳制为10)。 - 如果步进增量为非整数(例如
step="0.5"),则在blur时将输入值四舍五入到最近的步进增量。
- 在输入框
4. 实现键盘导航与触摸反馈
确保跨输入设备的无缝控制:
- 快捷键绑定:
ArrowUp/ArrowRight:按step增加数值。ArrowDown/ArrowLeft:按step减少数值。PageUp:按step * 10(或更大的步进增量)增加数值。PageDown:按step * 10(或更大的步进增量)减少数值。Home:将值设置为min(如果已定义)。End:将值设置为max(如果已定义)。
- 长按自动重复: 当用户(通过指针或键盘)按住增加/减少按钮时,在 500ms 初始延迟后启动数值自动重复,每 100ms 循环一次。
- 触摸/移动键盘: 在
<input>元素上设置inputmode="numeric"或inputmode="decimal"以及pattern="[0-9]*",以在移动设备上触发数字键盘,而无需强制使用标准的原生浏览器微调器。
5. 配置无障碍和屏幕阅读器语义
提供 WCAG 2.1 / 2.2 AA 合规体验:
- 语义 HTML 选项:
- 选项 A(带步进器按钮的原生输入): 使用与显式
<label>关联的<input type="text" inputmode="numeric">。使用<button type="button" aria-label="减少数量">和aria-controls="input-id"来标注减少/增加按钮。 - 选项 B(ARIA Spinbutton 角色): 在容器或输入上应用
role="spinbutton"、aria-valuenow="3"、aria-valuemin="1"、aria-valuemax="10"、aria-valuetext="3 个席位"和aria-label="选择席位数量"。
- 选项 A(带步进器按钮的原生输入): 使用与显式
- 焦点环管理: 保持可见的高对比度焦点环(
outline: 2px solid var(--focus-ring); outline-offset: 2px;)围绕活动按钮和文本输入。焦点环绝不能隐藏或被父容器边界裁剪。 - 实时区域通告: 使用
aria-live="polite"或动态更新aria-valuenow,以便辅助技术能在按钮按下时立即通告数值变化。
决策规则
组件模式矩阵
| 使用场景 | 推荐变体 | 按钮放置 | 最小/最大值策略 |
|---|---|---|---|
| 电商商品详情页 | 标准水平式 | 两侧(- 左,+ 右) | 最小值 = 1(或在值为 1 时显示删除图标),最大值 = 库存限制 |
| 购物车行项目 | 紧凑水平式 / 删除混合式 | 两侧(-/删除图标 左,+ 右) | 最小值 = 0(删除项目),最大值 = 可用库存 |
| SaaS 账单席位 | 水平式带单位后缀 | 两侧(- 左,+ 右) | 最小值 = 最低计划层级,最大值 = 账户上限 |
| 桌面数据表 | 内联堆叠步进器 | 尾部堆叠(▲ 上, ▼ 下) | 失焦时钳制到最小/最大值 |
| 金融金额 | 带单位输入框($) | 可选两侧按钮或仅手动输入 | 最小值 = 0,最大值 = 限制并附带验证消息 |
直接输入 vs. 仅按钮规则
- 允许直接输入(默认): 对于数量 > 5 或用户可能直接输入大数字(例如订购 50 件或设置 $500 预算)的情况。
- 仅限制按钮输入(
readonly输入框): 仅当值范围非常小(例如 1 到 5)且自由文本输入在小型触摸设备上会引入不必要的验证开销时使用。
约束
- 无障碍(WCAG 2.1 / 2.2 AA):
- 按钮必须提供描述操作的显式
aria-label属性(例如“减少商品数量”)。 - 增加和减少按钮必须在触摸视口上保持最小 44x44px 的触摸目标(SC 2.5.8)。
- 活动焦点指示器必须满足 WCAG 2.4.11(焦点未被遮挡)和 SC 2.4.13(焦点外观)。
- 按钮必须提供描述操作的显式
- 数字格式:
- 绝不允许在失焦时输入框内保留空白或
NaN值。回退到min或上一个有效值。 - 数字必须使用
font-variant-numeric: tabular-nums;渲染,以防止在增量期间发生布局重排。
- 绝不允许在失焦时输入框内保留空白或
- 移动软键盘:
- 始终设置
inputmode="numeric"(或decimal),以在 iOS/Android 上打开标准数字键盘。通过在 CSS 中禁用原生微调器(::-webkit-inner-spin-button)来避免原生<input type="number">的默认箭头样式。
- 始终设置
常见失败模式
- 微小且非标准的触摸目标: 在手机上使用 18x18px 的 V 形按钮,导致误触和用户沮丧。
- 依赖浏览器原生
<input type="number">: 允许浏览器默认的微调器渲染不一致、覆盖自定义文本填充或触发意外滚动调整。 - 缺少边界禁用提示: 当
value === min时,减少按钮仍保持视觉活动状态,导致用户点击后无反馈。 - 未钳制的自由输入: 允许用户输入无效值(例如
-5或999999),而在失焦时没有钳制或错误反馈。 - 缺少键盘支持: 设计自定义
<div>按钮时,缺乏Tab焦点支持和ArrowUp/ArrowDown事件处理。
验证标准
- 减少和增加按钮在触摸视口上满足最小 44x44px 的触摸目标。
- 使用等宽排版(
tabular-nums)以防止更新期间布局抖动。 - 在最小和最大限制时,相应的按钮过渡到禁用状态(
aria-disabled="true")。 - 移动端输入使用
inputmode="numeric"或inputmode="decimal"。 - 组件正确处理
ArrowUp、ArrowDown、PageUp、PageDown、Home和End键。 - 配置了程序化标签(
aria-label或<label>)和 ARIA 角色(role="spinbutton"或显式的aria-controls按钮)。 - 超边界输入的值在
blur时自动钳制或触发验证错误消息。 - 高对比度焦点指示器可见且未被遮挡。