如何使用单个HTML input实现按位分割的短信验证码PIN输入框
单个 <input> 完全可以实现你要的分割式验证码效果,不需要叠加额外DIV覆盖,纯CSS样式即可实现,同时满足无障碍、自动填充、复制粘贴无需额外逻辑的要求,适配React+MUI也非常简单。

核心实现思路
核心原理是通过等宽字体控制字符宽度+字符间距拉开字符距离+渐变背景模拟分割输入框,所有样式都作用在原生input元素上,没有额外DOM层,天然支持原生input的所有能力。
原生HTML/CSS实现示例
HTML代码
<input type="text" maxlength="6" inputmode="numeric" autocomplete="one-time-code" class="verify-code-input" >
CSS代码
.verify-code-input { /* 基础尺寸 */ width: 280px; height: 48px; padding: 0 8px; border: none; outline: none; /* 等宽字体保证每个字符宽度一致 */ font-family: monospace; font-size: 32px; /* 字符间距:调整到刚好每个字符落在对应格子里,根据实际尺寸微调 */ letter-spacing: 24px; /* 渐变背景模拟分割框:每个格子宽度40px,边框占10%位置 */ background-image: linear-gradient(to right, #e5e7eb 95%, transparent 95%); background-size: 40px 100%; /* 下边框可选 */ border-bottom: 1px solid #d1d5db; /* 光标样式调整 */ caret-color: #2563eb; } /* 选中样式优化 */ .verify-code-input::selection { background-color: #bfdbfe; }
React + MUI适配方案
直接使用MUI的TextField组件,通过sx属性注入自定义样式即可,无需额外封装逻辑:
import TextField from '@mui/material/TextField'; const VerifyCodeInput = () => { return ( <TextField type="text" inputProps={{ maxLength: 6, inputMode: 'numeric', autoComplete: 'one-time-code', sx: { fontFamily: 'monospace', fontSize: '32px', letterSpacing: '24px', backgroundImage: 'linear-gradient(to right, #e5e7eb 95%, transparent 95%)', backgroundSize: '40px 100%', paddingLeft: '8px', border: 'none', borderBottom: '1px solid #d1d5db', caretColor: '#2563eb', '&::selection': { backgroundColor: '#bfdbfe' } } }} variant="standard" sx={{ width: '280px' }} /> ) }
方案优势
- 完全基于原生input实现,无障碍友好,读屏设备可以正常识别、读取内容
- 不需要额外处理字符跳转、粘贴拆分逻辑,原生input自动支持全选复制、粘贴整段验证码自动填充
- 没有额外DOM层,不需要覆盖DIV,响应式适配简单,调整width和backgroundSize即可适配不同屏幕尺寸
- 支持浏览器原生短信验证码自动填充功能,体验更好
内容的提问来源于stack exchange,提问作者AK_
相关产品推荐
相关产品推荐

