dt 和 dd 必须包裹在 dl 中,否则语义失效;一个 dt 可对应多个 dd,但 dd 不能悬空或跨 dt 共享;需重置默认样式并添加 aria 属性与 js 交互以满足无障碍要求。

dt 和 dd 必须包裹在 dl 中,否则语义失效
单独写 <dt></dt> 或 <dd></dd> 标签浏览器不会报错,但会丢失结构语义,屏幕阅读器无法识别为问答对,SEO 也几乎不识别。必须用 <dl></dl> 作为容器,且 <dt></dt> 和 <dd></dd> 要成对嵌套在其中。
-
<dl></dl>是定义列表(definition list)的唯一合法父元素,不是可选的“装饰”标签 - 一个
<dt></dt>可对应多个<dd></dd>(比如一个问题带多条解释),但一个<dd></dd>不能悬空在<dl></dl>外 - 常见错误:把
<dt></dt>当成<h3></h3>用、或用<div> 替代 <code><dl></dl>—— 这会让辅助技术完全忽略问答关系多个问题共用同一答案时,dt 可重复,但 dd 不能跨 dt 共享
HTML 规范不允许一个
<dd></dd>同时属于多个<dt></dt>。如果两个问题指向同一段解释,必须复制一份<dd></dd>,或改用 JavaScript 动态展开/收起逻辑,而不是靠 DOM 结构“偷懒”。- 错误写法:
<dt>Q1</dt> <dt>Q2</dt> <dd>同一答案</dd>—— 浏览器解析时会把第二个<dt></dt>视为无<dd></dd>的孤立项 - 正确做法:每个
<dt></dt>后紧跟它自己的<dd></dd>,哪怕内容相同 - 若答案很长且重复多,建议用 CSS 类名统一控制样式,而非合并 DOM 节点
样式重置比想象中更关键:浏览器默认有 margin 和缩进
不同浏览器对
<dl></dl>、<dt></dt>、<dd></dd>的默认 margin 差异很大,特别是<dd></dd>默认带左侧缩进(40px 左右),直接导致 FAQ 排版错乱。- 必须重置:
dl, dt, dd { margin: 0; padding: 0; },再按需添加间距 -
<dt></dt>默认不加粗、无特殊字体,常需手动设font-weight: bold或cursor: pointer - 移动端要注意
<dd></dd>内部段落(<p></p>)的 margin 会叠加,容易撑开过大间隙
无障碍支持依赖正确的 aria 属性和焦点管理
仅靠
<dl></dl>结构不足以满足 WCAG 2.1,用户无法键盘操作展开/收起,屏幕阅读器也无法播报“已展开/已折叠”状态。- 给每个
<dt></dt>加tabindex="0"和role="button",使其可聚焦、可按键触发 - 用
aria-expanded="true/false"控制状态,并配合aria-controls="id-of-dd"关联对应<dd></dd> -
<dd></dd>需设id与aria-controls值一致,且初始隐藏时加hidden或aria-hidden="true"
复杂点在于:纯 HTML 无法实现交互,必须配 JS 控制显隐和属性切换;而很多人只写结构、不补逻辑,结果对键盘用户和读屏软件完全不可用。
- 错误写法:











