<optgroup>是语义化、无障碍友好的原生下拉分组方案,需严格遵循结构规范:仅直接嵌套于<select>内、包裹<option>、label属性不可为空且不解析HTML;禁用整组用disabled属性;动态插入须用select.add();样式定制受限,高级功能应选用JS组件。

用 <optgroup> 标签就能对下拉选项做原生分组,它不是装饰,而是语义化、无障碍友好的标准方案。
必须写对结构和属性
<optgroup> 只能直接放在 <select> 里面,不能套在 <div> 里,也不能嵌套另一个 <optgroup>。它只允许包裹 <option>,其他内容(包括空格、注释、文本)都可能让浏览器静默忽略整组。
- label 属性不可省略,且不能是空字符串、纯空格或仅含空白符;写成
label=""或label=" "就等于没写 - 中文 label 建议控制在 2–4 字,比如“华东”“待审核”,避免“其他分类”这类模糊表述
- label 值不解析 HTML,
label="<strong>水果</strong>"会原样显示为文字,不会加粗
禁用整组要加在 optgroup 上
给 <optgroup disabled> 加 disabled,内部所有 <option> 都会变灰且不可选,但分组标题(label)依然可见——这是规范行为,不是失效。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- 不要用 CSS 模拟禁用,比如
style="pointer-events: none",键盘仍可聚焦、屏幕阅读器可能误读 - 如果想让某组彻底不出现,得用 JS 移除整个
<optgroup>节点,或服务端不输出该标签 - 单独禁用某个选项,直接给对应
<option disabled>加属性即可
动态插入要注意方法和顺序
JS 创建分组时,不能用 appendChild() 往 <select> 添加 <optgroup>,否则会报错或静默失败。
立即学习“前端免费学习笔记(深入)”;
- 正确做法:先创建
<optgroup>元素,再显式赋值optgroup.label = "xxx",最后调用select.add(optgroup) - 往
<optgroup>内添加<option>时,可以用optgroup.appendChild(option) - 设置默认选中项(如
select.value = "sh")前,确保对应<option>已插入 DOM,否则赋值会被丢弃
样式定制空间很小,别强求
浏览器对 <optgroup> 的 CSS 支持非常有限:
- color、font-weight 在部分浏览器中可用,但 background-color、padding、margin 基本无效
- iOS Safari 原生下拉菜单中,
<optgroup>的 label 通常完全不显示,只渲染<option> - 需要图标、悬停、搜索等高级功能,应改用 JS 实现的下拉组件(如 Choices.js),而非硬改原生样式


















