原生HTML无<input type="tag">,标签式多选需用<div>+<button>+JS实现;<select multiple>交互反直觉、移动端难操作、无法直观展示已选项,故必须放弃;核心结构为容器内含标签列表(带data-value的<button>)和下拉触发器。

原生 HTML 没有 <input type="tag"> 或类似“多选标签输入框”的标准元素——你看到的带删除 × 的标签式多选,全是用 <div> + <button> + JavaScript 模拟出来的。
为什么不能直接用 select multiple?
它确实支持多选,但交互反直觉:用户得按住 Ctrl/Cmd 才能点选,移动端 Safari 几乎无法操作;默认只显示一行,不设 size 就看不出是多选;已选项堆在下拉里,无法在输入区域直观展示。真正做“标签式输入”,必须放弃原生 select。
- 设了
multiple但没设size→ 界面和单选一模一样,用户根本不会去 Ctrl+Click - 用 JS 读
selectedOptions可以取值,但无法把已选项“贴”到输入框上方变成可点击删除的标签 - 无障碍支持虽好,但语义上它仍是“列表选择”,不是“动态标签输入”
核心结构:用 div 模拟输入区 + button 模拟标签
真实项目中,所谓“多选标签输入框”,本质是一个容器,里面放两部分:已选标签列表(每个是 button 带 data-value),和一个触发下拉的按钮(或输入框)。
- 标签按钮建议用
<button type="button">,避免意外提交表单 - 每个标签 button 加
data-value="xxx",方便 JS 统一读取、提交、去重 - 不要用
id标识单个标签——动态增删时 ID 容易重复,改用data-属性存业务数据 - 下拉内容区通常用
<div class="dropdown-content">,配合 JS 控制show/hide,不依赖select
input 元素本身不支持多选标签,别被命名误导
HTML 中所有带 multiple 的地方,只对三类元素有效:<select>、<input type="file">、<input type="email">(后者仅限某些浏览器解析逗号分隔邮箱)。<input type="text"> 或 <input type="search"> 加 multiple 属性完全无效,浏览器会忽略。
立即学习“前端免费学习笔记(深入)”;
- 想让用户“输入关键词 + 回车生成标签”?必须监听
keydown(判断 Enter)或blur(失焦时提交),然后手动创建 button 插入容器 - 用
contenteditable+div是另一条路,但光标管理、粘贴处理、移动端兼容性更复杂,不推荐初手碰 - 如果只是静态选项(比如“前端/后端/测试”几个固定标签),直接渲染 button 列表 + JS 绑定 toggle 逻辑就够了,不用模拟下拉
最常漏掉的兼容性细节
移动端点击标签 × 删除时,容易误触下拉展开;Safari 对 focus() 和 blur() 的触发时机和顺序跟 Chrome 不一致;还有就是键盘操作支持——用户用 Tab 进入后,按空格或 Enter 应该切换选中状态,但很多实现只响应鼠标 click。
- 删除按钮必须加
aria-label="删除 xxx",否则屏幕阅读器读不出作用 - 已选标签容器要设
role="list",每个标签 button 设role="listitem",保证语义正确 - 别用
document.activeElement判断焦点位置——它在 iOS Safari 上经常不准,改用事件委托监听focusin/focusout


















