optgroup 必须嵌套在 select 内,label 为必填纯文本属性且不可为空或含 html 实体,不支持 disabled 属性和样式定制,移动端显示受限,超长 label 易截断。

optgroup 必须嵌套在 select 里,不能单独使用
直接写 <optgroup></optgroup> 标签而不包裹在 <select></select> 中,浏览器会忽略它,甚至可能把内容渲染到页面顶部。这是新手最常犯的错误——以为 optgroup 是独立控件。
正确结构只有这一种:<select></select> → 多个 <optgroup label="xxx"></optgroup> → 每个里面放若干 <option></option>。
示例片段:
<select name="city"><optgroup label="广东省"> <option value="gz">广州</option> <option value="sz">深圳</option> </optgroup> <optgroup label="江苏省"> <option value="nj">南京</option> <option value="sz">苏州</option> </optgroup></select>
label 属性值不可为空,且不支持 HTML 实体或换行
label 是必填属性,空字符串(label="")会导致该分组标题不可见,部分浏览器还会降级为普通 option 行为;更隐蔽的问题是:如果用 或 <br> 试图美化标题,它们会被原样显示为文字,而非渲染效果。
实际使用建议:
- 用纯文本,如
label="浙江省",避免空格开头/结尾 - 中文标点统一用全角,但不要混入 emoji 或特殊符号(某些旧版 Safari 会截断)
- 如果需要动态生成,确保后端或 JS 拼接前已 trim 过空白
optgroup 不支持 disabled,但可让内部 option 全部禁用
你不能对 <optgroup disabled></optgroup> 加禁用状态(HTML 规范不支持),浏览器会静默忽略这个属性。想“灰掉”整个省份的选项,得手动给每个 <option></option> 加 disabled。
常见误操作:
- 只写
<optgroup label="西藏" disabled></optgroup>→ 无效,城市仍可选 - 漏掉某个
<option></option>的disabled→ 用户能意外选中它
推荐做法:服务端或 JS 初始化时,统一处理某组下的所有 option 节点,批量添加 disabled 属性,而不是依赖 optgroup 自身控制。
移动端下 optgroup 样式不可定制,慎用长 label
iOS Safari 和 Android Chrome 对 optgroup 的样式支持极弱:font-size、color、padding 基本无效,且 label 文字默认比 option 小、加粗,但无法调整。更关键的是,当 label 字数过多(比如“内蒙古自治区”+“(含阿拉善盟等12个地级行政区)”),iOS 系统选择器会自动折行或截断,用户看不到完整分类名。
务实建议:
- label 控制在 6 个汉字以内,优先用简称:“广东”优于“广东省”,“新疆”优于“新疆维吾尔自治区”
- 别指望用 CSS 改变 optgroup 的外观,连
select::-webkit-scrollbar都不适用它 - 如果业务强依赖清晰分组和美观样式,考虑改用自定义下拉组件(如 Select2、Choices.js),而非原生
select+optgroup
原生 optgroup 的价值在于语义正确、无障碍支持好、零 JS 依赖,但它的视觉控制力几乎为零——这点很容易被开发初期忽略。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











