
HTML 中隐藏的宝藏:<dl> 标签完全使用指南
详细介绍 HTML <dl> 描述列表标签的语义、用法和最佳实践,包括多值、分组、无障碍访问等进阶技巧
原文来源:Ben Myers - "On The <dl>" — HTML <dl>(描述列表)是一个被严重低估的语义化标签,它能标记各种"名值对"数据,从书籍信息到游戏角色属性卡都适用。
引言
在 HTML 标签的大家庭中,有些标签备受关注,比如 <div> 几乎是所有前端开发者的"瑞士军刀";有些标签争议不断,比如 <table> 经历过"用表格还是不用表格"的时代论战。但还有一个标签,明明非常实用,却很少有人真正用好它——那就是 <dl>。
<dl> 的全称是 Description List(描述列表),它用于表示一组名称-值对的列表。这个模式在网页中出现的频率远超你的想象:
- 产品规格:尺寸、重量、材质
- 书籍信息:标题、作者、出版社
- 账户详情:用户名、邮箱、注册日期
- 属性面板:各种键值对数据
你会发现,网页上到处都是"名称→值"这样的信息结构。而 <dl> 就是 HTML 专门为此设计的语义化方案。
基本结构:三兄弟的故事
<dl> 其实是一个"三兄弟"的组合。除了 <dl> 本身,还有两个子元素:
<dt>(Description Term)—— 名称部分<dd>(Description Detail)—— 值部分
最简单的例子:
<dl>
<dt>书名</dt>
<dd>Web 标准设计</dd>
</dl>这段代码声明了一个名称-值对:名称是"书名",值是"Web 标准设计"。
要增加更多条目,只需要继续添加 <dt> 和 <dd>:
<dl>
<dt>书名</dt>
<dd>Web 标准设计</dd>
<dt>作者</dt>
<dd>Jeffrey Zeldman</dd>
<dt>出版社</dt>
<dd>New Riders Pub;第三版 (2009年10月)</dd>
</dl>一对多:一个名称对应多个值
有时候,一个名称会对应多个值。比如一本书可能有多个作者:
<dl>
<dt>书名</dt>
<dd>Web 标准设计</dd>
<dt>作者</dt>
<dd>Jeffrey Zeldman</dd>
<dd>Ethan Marcotte</dd>
<dt>出版社</dt>
<dd>New Riders Pub;第三版 (2009年10月)</dd>
</dl>没错,一个 <dt> 可以跟多个 <dd>。这在语义上是完全合法的,浏览器也会正确渲染。
分组包装:用 <div> 包裹每组
如果你需要对每组名称-值对进行样式控制,HTML 规范允许在 <dl> 内部使用 <div> 包裹 <dt> 和 <dd> 的组合:
<dl>
<div>
<dt>书名</dt>
<dd>Web 标准设计</dd>
</div>
<div>
<dt>作者</dt>
<dd>Jeffrey Zeldman</dd>
<dd>Ethan Marcotte</dd>
</div>
<div>
<dt>出版社</dt>
<dd>New Riders Pub;第三版 (2009年10月)</dd>
</div>
</dl>注意:在 <dl> 内部,<div> 是唯一可以包裹 <dt>/<dd> 组合的元素。你可以用 <div> 来给每组添加类名、绑定事件监听器、或者实现 Flexbox/Grid 布局。
为什么不用 <div> 加类名?
很多团队在遇到"名称-值对"这种模式时,第一反应就是:
<div class="book-details">
<div class="book-details--item">
<div class="book-details--label">书名</div>
<div class="book-details--value">Web 标准设计</div>
</div>
<div class="book-details--item">
<div class="book-details--label">作者</div>
<div class="book-details--value">Jeffrey Zeldman</div>
</div>
</div>这段代码在视觉上和 <dl> 版本没有区别。那为什么还要用 <dl>?
因为语义。语义化的 HTML 不仅是给人看的,更是给机器看的。当我们问一个问题:"如果计算机能识别这种模式,能带来什么好处?"
答案很明确:
对屏幕阅读器的好处
- 导航便利:屏幕阅读器可以告诉用户"这是包含 N 个条目的描述列表"
- 快捷跳转:用户可以在列表之间快速跳转,而不是逐个遍历文本节点
- 结构清晰:每个名称和值的对应关系一目了然,不会混淆
这些不是理论上的假设——在大多数浏览器和屏幕阅读器的组合中,使用 <dl> 确实能给视障用户带来更好的体验。相比之下,嵌套 <div> 方案会让屏幕阅读器把每个名称和值都当成独立的文本节点,完全丢失了结构信息。
实战:龙与地下城角色属性卡
最有说服力的例子来了。Ben Myers 在原文中展示了一个龙与地下城(D&D)角色的属性卡——这简直是描述列表的"完美风暴",因为属性卡几乎全是"名称-值对"!
一块典型的 D&D 属性卡包含多个描述列表:
- 基础属性:护甲等级 (12)、生命值 (5)、速度 (30 ft.)
- 能力值:力量 (7)、敏捷 (15)、体质 (9)、智力 (8)、感知 (7)、魅力 (8)
- 技能:感官、语言、挑战等级
- 特性:阳光敏感、群体战术
- 动作:匕首、投石索
用 <dl> 标记起来的代码结构清晰,语义完整:
<div>
<h1>地精</h1>
<small>小型类人生物(地精),守序邪恶</small>
<dl>
<div>
<dt>护甲等级</dt>
<dd>12</dd>
</div>
<div>
<dt>生命值</dt>
<dd>5 (2d6 - 2)</dd>
</div>
<div>
<dt>速度</dt>
<dd>30 英尺</dd>
</div>
</dl>
<dl aria-label="能力值">
<div>
<dt>力量</dt>
<dd>7 (-2)</dd>
</div>
<div>
<dt>敏捷</dt>
<dd>15 (+2)</dd>
</div>
<!-- ... 更多属性 -->
</dl>
</div>这里有个值得注意的细节:多组 <dl> 之间用 aria-label 或 aria-labelledby 标注了不同的语义,让屏幕阅读器能清晰区分"基础属性"和"能力值"等不同的列表。
进阶技巧
1. 多值处理
当一个名称对应多个值时,使用多个 <dd>:
<dl>
<dt>编程语言</dt>
<dd>Python</dd>
<dd>JavaScript</dd>
<dd>Go</dd>
</dl>2. 无障碍属性
为 <dl> 添加 aria-label 或 aria-labelledby,帮助屏幕阅读器用户理解列表的上下文:
<dl aria-label="产品规格">
<!-- ... -->
</dl>3. CSS 布局
用 <dl> 结合 CSS Grid 可以轻松实现键值对的整齐布局:
dl {
display: grid;
grid-template-columns: auto 1fr;
gap: 0.5em 1em;
}但要注意:如果你的 <dl> 包含 <div> 包裹的组,CSS Grid 的布局会受到 <div> 的影响。这时可以直接 flex 布局或者直接给 <dt> 和 <dd> 分别设置宽度。
浏览器兼容性
<dl>、<dt>、<dd> 是 HTML 最早期的标签之一,在所有浏览器中都有完美的支持。需要注意的一点是:
- 用
<div>包裹<dt>/<dd>组:这是 HTML5 新增的规范特性。现代浏览器(Chrome、Firefox、Safari、Edge 的最新版本)都支持,但在非常老的浏览器中可能会有渲染问题。 - 如果你需要支持 IE11 或更老的浏览器,建议直接使用不带
<div>包裹的纯<dt>/<dd>序列。
总结
<dl> 是 HTML 中被低估最严重的标签之一。它的适用场景比大多数人想象的更广——任何"名称→值"的结构化数据都应该考虑使用它。
| 对比项 | 嵌套 div 方案 | <dl> 方案 |
|---|---|---|
| 语义化 | 无语义 | 强语义,明确表示名称-值对 |
| 无障碍 | 差,屏幕阅读器无法区分结构 | 好,支持列表导航和计数 |
| CSS 可访问性 | 灵活,但需要更多类名 | 灵活,选择器更简洁 |
| 代码量 | 多,需要大量类名 | 少,语义清晰 |
下次你在写一组"标签+值"的布局时,先想想:这个场景能不能用 <dl>?很可能可以。而且你的用户(尤其是使用屏幕阅读器的用户)会感谢你的选择。
© 2026 四月 · CC BY-NC-SA 4.0
原文链接:https://aprilzz.com/tutorials/html-dl-guide