一个很常见的前端页面:左边写“作者”,右边写“Ben Myers”;左边写“价格”,右边写“$19”;左边写“房型设施”,右边写“Wi‑Fi、早餐、停车”。
视觉上,这些内容用一堆 <div> 拼出来当然没问题。CSS 一套,网格一拉,页面照样漂亮。
但机器看到的,可能只是一堆散落文本。
这就是 HTML 列表语义讨论里最容易被低估的一块:列表不只有 <ul> 和 <ol>。很多网页上的“详情项”“属性块”“费用明细”,真正该先想的是 <dl>。
Ben Myers 在《On The <dl>》里把这件事说得更具体:<dl> 不是古早术语表专用标签,它适合表达一组名称—值关系。这个补充很要紧,因为它把讨论从“语义化理念”拉回了前端每天都要写的组件。
发生了什么:<dl> 被重新拉回名称—值场景
<dl> 的全称是 description list。
老开发者容易把它记成 definition list,也就是“定义列表”。这个历史包袱害人不浅。很多人因此以为它只能写术语解释:
- HTML.超文本标记语言
- CSS.层叠样式表
- DOM.文档对象模型
但 WHATWG 和 MDN 现在更强调的是:<dl> 用来表示一组名称—值对,或者名称—值组。
基本结构很简单:
<dl>.包住整组描述列表<dt>.名称,term/name<dd>.描述或值,description/value
一个 <dt> 可以对应多个 <dd>。比如一本书的 Author 可以有两位作者。一个页面的 Facilities 也可以有多个设施项。
更现实的一点是,如果为了样式需要包一组 <dt> 和 <dd>,规范允许在 <dl> 里用 <div> 做分组包装。
边界也很清楚:这个 <div> 是分组用的,不是让你把 <dl> 当成万能布局盒。
怎么选:别按长相选,按关系选
前端写列表,最常犯的错是按视觉形态选标签。
看着像一列,就用 <ul>。看着像两列,就用 <table>。懒得想,就全用 <div>。
这套习惯很省事,也很粗糙。
更稳的判断是看内容关系:
| 标签 | 适合场景 | 判断点 |
|---|---|---|
<dl> | 商品参数、书籍元信息、费用明细、住宿设施、游戏属性 | 有明确“名称—值”关系 |
<ul> | 菜单项、功能点、普通清单 | 一组同类项目,不负责解释键值关系 |
<ol> | 步骤、排名、时间顺序 | 顺序本身有意义 |
<table> | 对账单、规格矩阵、成绩表 | 需要按行列标题交叉读取 |
<div> | 布局容器、无语义分组 | 只解决样式,不表达内容关系 |
这里不能把话说死。
有些价格明细适合 <dl>:服务费 10 元,配送费 5 元,优惠 -3 元。它就是项目名—金额。
但有些账单更像表格:日期、订单号、项目、税费、总额、多列交叉对比。这时硬塞 <dl> 反而别扭。
关键不是“长得像不像表格”,而是用户是否需要靠行列标题来理解数据。
这也是 Ben Myers 那篇文章真正补强的地方:它没有停在“少写 div”这种表层建议,而是把 <dl> 放进了商品参数、书籍信息、住宿设施、游戏属性这些高频业务场景里。前端团队一看就知道,这不是考古,这是日常工作。
为什么重要:语义化的账,主要由屏幕阅读器用户来付
普通视觉用户看页面,常常不会感受到差别。
一个电商详情页有十几项规格。视觉用户扫一眼,知道这块是参数,不想看就跳过。
屏幕阅读器用户不一样。
如果页面只是一串 <div>:
- “品牌 Apple”
- “型号 iPhone”
- “存储 256GB”
- “颜色 黑色”
辅助技术未必知道这是一组列表,也未必能告诉用户列表长度、当前位置、区块边界。
这会增加浏览成本。用户不知道自己在第几项,也不容易快速跳过整块参数。
<dl> 至少给了浏览器和辅助技术一个机会:这里是一组描述列表,这些内容存在名称和值的关系。
我说“机会”,不是说“保证”。
根据 a11ysupport.io 对 <dl> 的测试,不同浏览器、屏幕阅读器组合对它的支持并不完全一致。工程团队不能把 <dl> 当万能药。某些场景下,<ul> 加清晰文案,或者额外 ARIA 标注,可能更稳。
但这不构成继续滥用 <div> 的理由。
“工欲善其事,必先利其器。”HTML 本身就是第一层工具。你一开始把结构写坏,后面再靠 ARIA 缝缝补补,很多时候是在替错误还债。
谁最受影响:不是普通读者,是组件库和可访问性负责人
这事对普通用户的直接感知很弱。
页面不会因为 <div> 换成 <dl> 立刻变得更漂亮。老板也不会因为代码里多了几个语义标签就鼓掌。
真正受影响的是两类人。
一类是做设计系统和组件库的前端团队。
如果一个组件叫“详情项”“属性列表”“规格参数”“费用拆分”,它就不该默认从 <div> 开始。组件设计阶段就该问一句:这是不是稳定的名称—值结构?
是,就优先评估 <dl>。
这比上线后做可访问性审计,再补 role、aria-label、隐藏文本,干净得多。
另一类是负责可访问性的团队。
可访问性不是最后一轮检查表。很多问题不是“缺一个属性”,而是底层结构一开始就没写对。
一个满屏 <div> 的页面,就像一座没有路牌的商场。视觉用户还能靠空间感走,屏幕阅读器用户只能听人一间一间报门牌。
我的判断:语义化不是洁癖,是工程纪律
前端行业有个很坏的惯性:只要视觉还原过关,结构就被当成小事。
这套激励很现实。排期看截图,验收看像不像设计稿,性能看分数,转化看按钮。HTML 语义这种东西,既不酷,也不好截图汇报。
于是最基础的结构反而最容易被糊弄。
问题不在开发者不会写 <dl>。问题在团队没有把“什么内容该用什么结构”变成组件规范。
很多前端嘴上讲工程化,手里写的是视觉拼装。页面像素级还原,DOM 语义一地鸡毛。模型能读图,浏览器却读不懂你的文本结构,这很讽刺。
我不太买账“现在都组件化了,HTML 标签没那么重要”这种说法。
组件化不是语义化的替代品。组件只是把错误批量复制得更快。如果组件库里的“参数项”从第一天就是 <div><span><span>,后面每个业务线都会继承这个懒惰。
这才是 <dl> 讨论真正刺到人的地方。
它不是在提醒你多认识一个标签。它是在提醒团队:别把网页写成给人眼看的截图。网页首先是文档,其次才是界面。
历史上每一代界面技术都会重复这个问题。报纸排版进入网页时代,很多人把页面当成画布;Flash 时代更极端,漂亮但机器难读。今天换成组件、框架、设计系统,老毛病还在,只是包装更现代。
不完全一样,但权力结构很像:视觉层最容易被看见,也最容易拿走预算;结构层最安静,坏了却由最弱势的用户承担成本。
天下熙熙,皆为利来。前端工程里也一样。什么能被验收,什么就被认真对待。语义化要活下来,不能靠布道,得写进 lint、组件库、代码评审和验收标准。
接下来该看什么:不是 <dl> 火不火,是规范进不进团队
<dl> 不会突然成为热门技术。
它也不需要热门。
真正该观察的是几件小事:
- 组件库里的“详情项 / 属性块 / 费用列表”默认结构有没有改
- 代码评审会不会问“这是清单、表格,还是名称—值列表”
- 可访问性测试有没有覆盖屏幕阅读器下的列表识别和跳转体验
- 团队是否承认
<dl>支持并不完美,并为关键页面做真实测试
这几个动作,比发一篇“语义化 HTML 最佳实践”有用。
好 HTML 不炫技。它只是让浏览器、搜索引擎、辅助技术和维护者少猜一点。
<ul>、<ol>、<dl>、<table>,这些标签看起来老,实际是在给内容划边界。边界清楚,后面的样式、交互、可访问性才有根。
满屏 <div> 的问题不是丑。它常常很漂亮。
问题是它把结构责任外包给了人眼。人眼能猜,机器不能总猜。用户一旦离开主流视觉浏览路径,代价就来了。
