如何用单个text输入实现单字符方格输入并解决字体适配问题?
单个Input实现字符方格输入效果的问题
我想实现一个输入效果:用单个text类型input,每个字符对应一个方格,最多支持20个字符,禁止使用多个input。想问下有没有不需要额外输入框的实现方式?
目前我已经做了一套方案,但调整字体大小时布局会错乱,求可行的解决办法。
当前实现代码
CSS代码
* { margin: 0; padding: 0; box-sizing: border-box; } body { padding: 2rem; } .input-container { display: flex; gap: 1rem; } .input-container input { height: 1rem; letter-spacing: 8px; font-size: 15px; border: none; outline: none; background-color: transparent; font-family: monospace; } .box-container { display: flex; position: absolute; top: 50%; transform: translate(0, -50%); z-index: -1; } .box { width: 16px; height: 16px; box-shadow: 0 0 0 1px rgba(0, 0, 0, 1); }
HTML代码
<body> <div class="input-container"> <label for="name">Nume</label> <div style="position: relative"> <input id="name" type="text" size="40" maxlength="20" /> <div class="box-container"> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> </div> </div> </div> </body>
问题分析与解决方法
问题根源
当前方案的核心问题是:方格尺寸、输入框字符间距、字体大小都是硬编码的固定值,彼此没有关联逻辑,调整字体大小时,字符位置和方格无法同步对齐,导致布局错乱。
优化后的实现方案
我们可以用CSS变量统一控制所有关联尺寸,用ch单位(等宽字体下1ch代表一个字符的宽度)保证字符与方格的对应关系,通过calc计算实现自适应对齐。
修改后代码
CSS代码
* { margin: 0; padding: 0; box-sizing: border-box; } /* 定义全局变量,方便统一调整 */ :root { --char-base-size: 1.2rem; /* 控制字体/方格的基础大小 */ --box-gap: 0.2rem; /* 方格之间的间距 */ } body { padding: 2rem; } .input-container { display: flex; gap: 1rem; align-items: center; } .input-wrapper { position: relative; /* 计算总宽度:20个方格宽度 + 19个方格间距 */ width: calc(20 * var(--char-base-size) + 19 * var(--box-gap)); } .input-wrapper input { width: 100%; font-size: var(--char-base-size); line-height: var(--char-base-size); /* 计算字符间距:让每个字符刚好落入对应方格 */ letter-spacing: calc(var(--box-gap) + var(--char-base-size) - 1ch); border: none; outline: none; background-color: transparent; font-family: monospace; padding: 0; } .box-container { display: flex; gap: var(--box-gap); position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: -1; } .box { flex: 1; height: 100%; box-shadow: 0 0 0 1px #000; }
HTML代码
<body> <div class="input-container"> <label for="name">姓名</label> <div class="input-wrapper"> <input id="name" type="text" maxlength="20" /> <div class="box-container"> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> <div class="box"></div> </div> </div> </div> </body>
关键改进点
- 用
--char-base-size变量统一控制字体大小和方格高度,修改这个值就能整体缩放,不会出现错位 - 通过
calc计算输入框总宽度和字符间距,确保每个字符刚好对应一个方格 - 方格用
flex:1均分宽度,和输入框宽度完全匹配 - 输入框行高与方格高度一致,垂直方向对齐稳定
关于“无需额外输入框”的实现说明
如果完全不用额外元素绘制方格,只能通过background-image线性渐变模拟,但这种方式很难精确控制20个方格的位置,字符与方格的对齐逻辑会异常复杂,几乎无法维护。上面的方案只用了额外的容器和方格元素,已经是最简洁且易维护的方式,完全满足“单个input”的核心要求。
内容的提问来源于stack exchange,提问作者Asstoped
相关产品推荐
相关产品推荐

