legend必须嵌套在fieldset中且为第一个子元素,否则标题不可见、无障碍失效;它不是独立标签,而是fieldset专属标题容器,脱离即被浏览器忽略,违反html语义结构硬性要求。

legend 必须嵌套在 fieldset 中且为第一个子元素,否则标题不可见、无障碍失效——这不是样式问题,是 HTML 语义结构硬性要求。
为什么 legend 单独写没反应
浏览器会直接忽略脱离 fieldset 的 legend:它不是独立语义标签,而是 fieldset 的专属标题容器。常见无效写法包括:
-
<legend>地址信息</legend> <input name="city">→ 无渲染、读屏器完全跳过 -
<div><legend>地址信息</legend></div>→ 违反 DOM 结构规范,legend不再是fieldset的直接子元素 -
<fieldset><div><legend>地址信息</legend></div></fieldset>→ WCAG 检查报fieldset-missing-legend
fieldset 里放什么、怎么放才合法
fieldset 的语义是“一组相关表单控件”,所有内容必须围绕交互目的组织:
-
legend必须是fieldset的第一个子节点,不能被任何包裹(div、span、注释等都不行) - 内部只应包含表单控件:
input、select、textarea、button、output等;避免混入p、h3、图片或说明段落 - 如需额外提示文字,可放在
legend内(如<legend>收货地址(必填)</legend>),或用aria-describedby关联外部div - 禁用整组时,直接给
fieldset加disabled属性,比逐个控制子元素更可靠
想自定义 legend 位置和样式怎么办
浏览器把 legend 视为边框的一部分,强行用 position: absolute 或 margin-left 移动会导致边框断裂、文字重叠:
- 安全可控的方式只有两种:
text-align: center或text-align: right控制文字对齐(不影响边框锚点) -
display: contents可拆解默认盒模型,但 IE 完全不支持,旧版 Safari 表现不稳定 - 若需要彻底自由布局(比如标题居右、带图标、响应式缩放),放弃
fieldset/legend,改用<section aria-labelledby="lbl1"><h3 id="lbl1">支付方式</h3></section>,并手动确保焦点进入时能读出组名
移动端和屏幕阅读器的隐性陷阱
别只看桌面端是否显示正常:
- iOS Safari 中,
optgroup的label常被完全隐藏,但fieldset/legend在主流 iOS 浏览器中仍有效;不过部分 Android 原生浏览器对legend朗读支持较弱 -
legend的可访问性价值远高于视觉效果:当焦点落在某个input上,读屏器会播报 “邮箱地址,联系信息组”,这个上下文无法靠 CSS 或label模拟 - 每个
fieldset只应有一个legend;多个会导致读屏器混淆分组归属,WCAG 2.1 直接判定为错误
真正难的不是写出能显示的标题,而是让标题在禁用状态、读屏模式、移动端缩放、CSS 重置后依然准确传递语义——这决定了用户能不能理解这组控件到底在干什么。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











