分组必须用语义标签:select 内唯一合法分组是 optgroup,需直接嵌套、带 label 属性、仅含 option;多选/单选必须用 fieldset 包裹,配 legend 且 name 带方括号,否则无障碍失效、后端收不到数组。

分组不是加个 class 或 div 就完事,得用语义正确的标签,否则表单逻辑错乱、无障碍失效、后端收不到数组——optgroup 和 fieldset 是唯二合规方案,选错就埋坑。
select 下拉菜单必须用 optgroup 分组
optgroup 是 select 内部唯一合法分组方式,浏览器和读屏软件都依赖它识别结构。写错位置或漏属性会直接失效。
-
optgroup必须直接嵌套在select里,不能包在div或其他标签中 - 必须带
label属性,比如<optgroup label="前端技术">,否则不渲染标题 -
optgroup自身不可选、无value、不提交,只起组织作用 - 内部只能放
option,不能嵌套另一个optgroup或div - 动态插入时,要用
select.add(optgroup),不能用appendChild(),否则 Chrome 报 DOMException
多选框/单选框必须用 fieldset 包裹
光靠相同 name 不算真正分组,fieldset 才是语义容器。没它,屏幕阅读器不知道这组 checkbox 是“兴趣爱好”还是“通知偏好”,后端也收不到数组。
-
fieldset必须配legend,且legend是第一个子元素,不可省略 - 同组所有
input的name必须一致,且带方括号:比如name="hobby[]",否则 PHP/Node.js 只收到最后一个值 - 给
fieldset加disabled会彻底禁用内部所有控件(包括legend点击),JS 事件也绑不上——想保留控制权,改用aria-disabled="true"+ CSS - iOS Safari 中
legend默认不响应点击,需额外加cursor: pointer和user-select: none
别混用 optgroup 和 fieldset
它们适用场景完全不同,强行混用会导致表单行为异常。
立即学习“前端免费学习笔记(深入)”;
-
optgroup只用于select内部,对checkbox或radio无效 -
fieldset不能塞进select,否则 HTML 验证失败,部分浏览器直接忽略整个select - 有人试图用
fieldset包option,结果选项全消失——option只能被select或optgroup直接包含 - 视觉分组需求(比如纯样式边框)不用
fieldset,改用div+ CSS,避免语义污染
最常被忽略的点:分组不只是为了好看。optgroup 影响 FormData 的遍历顺序,fieldset 决定后端是否能拿到数组;漏掉 legend 或写错 name[],调试时根本看不出问题,只会在提交后发现数据丢了。



















