自定义列表应使用而非或,其语义是描述术语()与定义(),必须成对出现且仅允许直接包含和,禁用文本、等其他元素。

自定义列表用 <dl></dl>,不是 <ul></ul> 或 <ol></ol>
很多人一看到“列表”就本能地去写 <ul></ul>,结果发现没项目符号、没序号,内容还乱排——因为自定义列表根本不是用来“编号”或“打点”的。<dl></dl> 的作用是描述术语和定义,结构上必须成对出现:<dt></dt>(definition term)放名词/标题,<dd></dd>(definition description)放解释或说明。
常见错误现象:直接在 <dl></dl> 里写文字、套 <p></p>、或者把多个 <dt></dt> 连着写没 <dd></dd>——浏览器会渲染异常,DevTools 里常报 “dl child element must be dt or dd”。
-
<dl></dl>内部只允许直接包含<dt></dt>和<dd></dd>,不能放文本、<p></p>、<div> 等 <li>一个 <code><dt></dt>可以对应多个<dd></dd>(比如一个术语有多个解释) - 一个
<dd></dd>也可以紧跟多个<dt></dt>(比如同义词共用一段解释),但语义上不推荐 - 嵌套时,
<dd></dd>里可以再放<dl></dl>,但<dt></dt>里不能
<dt></dt> 和 <dd></dd> 的缩进与换行不是自动的
浏览器默认会给 <dd></dd> 加左边距(通常是 40px),但不会自动换行或缩进对齐。如果你写:
- HTML
- 超文本标记语言
- CSS
- 层叠样式表
效果可能挤在一起,尤其在窄屏下。这不是 bug,是规范行为——<dt></dt> 和 <dd></dd> 是并列兄弟元素,不是父子关系。
- 想让每个
<dt></dt>/<dd></dd>占一行,得手动换行或加<br>(不推荐) - 更合理的方式是用 CSS 控制:比如给
<dd></dd>加margin-top: 0.5em或用display: block强制换行 - 移动端要注意:默认缩进在小屏幕上可能过大,建议用
margin-inline-start: 1em替代固定像素值
别把自定义列表当“多级菜单”或“FAQ 折叠区”来用
有人试图用 <dl></dl> 做问答页面,比如:
- Q:怎么插入图片?
- A:用
<img>标签…
这语法没错,但语义错位:<dt></dt> 应该是被定义的“概念”,不是问题句式;<dd></dd> 是它的解释,不是回答模板。搜索引擎和读屏软件会按术语-定义逻辑解析,Q&A 更适合用 <section></section> + <h3></h3> + <p></p>。
- 真正适合
<dl></dl>的场景:词汇表、参数说明(如 API 文档里的offset字段)、HTML 属性对照表 - 如果需要交互(点击展开/收起),
<dl></dl>本身不提供,得配合 JS +details/summary或 CSS:has()(注意兼容性) - W3C 明确说:
<dl></dl>不用于标记对话、步骤、目录——那些该用<ol></ol>或<nav></nav>
浏览器对空 <dd></dd> 的处理很随意
写 <dd></dd> 但里面没内容,比如:
- 兼容性
Chrome 会渲染出一段空白缩进,Firefox 可能完全忽略,Safari 有时连 <dt></dt> 都错位。这不是 bug,是规范未定义空 <dd></dd> 的表现方式。
- 空
<dd></dd>在可访问性上等于“无定义”,屏幕阅读器会跳过或报错 - 如果某个术语暂无解释,宁可删掉整组
<dt></dt> <dd></dd>,也不要留空<dd></dd> - 想占位又不想暴露给辅助技术?用
<dd aria-hidden="true"> </dd>,但优先考虑是否真需要这个术语
自定义列表的关键在于“术语-定义”这一对一(或多对一)的语义绑定,而不是视觉排版。写之前先问一句:这里是不是真有一个需要被明确定义的概念?如果不是,<ul></ul> 或 <ol></ol> 往往更合适。











