大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
HTML 列表
这一课你将能做到
- 用 ul/ol/li 搭建正确嵌套的多层级列表,知道两者语义区别
- 用 dl/dt/dd 写出准确的「术语-解释」型列表,如 FAQ、配置说明
- 通过 CSS
list-style-type改变项目符号样式,理解浏览器默认与自定义的差异
为什么要学
列表是网页中使用频率仅次于段落的文本结构:导航菜单、商品分类、文章目录、功能特性、API 参数说明……几乎每页都有。用对列表标签不仅影响视觉呈现,更直接影响屏幕阅读器的播报方式和搜索引擎对页面结构的解析——把一组并列项写成逗号分隔的字符串,机器读出来就是一锅粥。
人话:列表就像超市货架上的分类标签,告诉顾客「这些是同类商品」「这些有先后顺序」。不用标签,顾客只能在一堆商品里硬找。
先建立图像
三种列表的语义对比:
无序列表 ul:
● 功能特性(无优先级)
● 多选题选项
● 导航菜单
有序列表 ol:
1. 操作步骤(有顺序)
2. 排行榜(有排名)
3. 目录(有层级)
定义列表 dl:
术语 dt
解释 dd
术语 dt
解释 dd
核心判断标准:有先后/序号意义用 ol,纯并列用 ul,名词+解释对用 dl。
跟着做
步骤 1:无序列表
新建 lists.html:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>列表演示</title>
</head>
<body>
<h2>技术栈</h2>
<ul>
<li>Java</li>
<li>Spring Boot</li>
<li>MySQL</li>
<li>Redis</li>
</ul>
</body>
</html>
浏览器默认显示黑色实心圆点(disc)。注意:li 必须是 ul/ol 的直接子元素,中间不能插 div 或 p。
步骤 2:有序列表
<h2>部署步骤</h2>
<ol>
<li>打包项目:mvn clean package</li>
<li>上传服务器:scp target/app.jar root@host:/opt/</li>
<li>启动服务:java -jar /opt/app.jar</li>
<li>验证接口:curl http://localhost:8080/health</li>
</ol>
浏览器默认显示 1、2、3、4。改序号类型:
<ol type="A">
<li>需求分析</li>
<li>系统设计</li>
<li>开发实现</li>
</ol>
type 可选值:1(默认数字)、a(小写字母)、A(大写字母)、i(小写罗马数字)、I(大写罗马数字)。
从指定数字开始:
<ol start="5">
<li>第五条</li> <!-- 显示 5 -->
<li>第六条</li> <!-- 显示 6 -->
</ol>
倒序:
<ol reversed>
<li>最后一步</li> <!-- 3 -->
<li>中间一步</li> <!-- 2 -->
<li>第一步</li> <!-- 1 -->
</ol>
步骤 3:嵌套列表
<h2>前端技术分类</h2>
<ul>
<li>HTML
<ul>
<li>语义化标签</li>
<li>表单</li>
</ul>
</li>
<li>CSS
<ul>
<li>布局:Flexbox、Grid</li>
<li>响应式</li>
</ul>
</li>
<li>JavaScript
<ol>
<li>基础语法</li>
<li>DOM 操作</li>
<li>异步编程</li>
</ol>
</li>
</ul>
嵌套规则:ul 里嵌 ul/ol 都可以;但必须嵌在 li 内部。<li>...</li> 之间放入新的 ul/ol 即可。
步骤 4:定义列表
<h2>常用术语</h2>
<dl>
<dt>API</dt>
<dd>应用程序编程接口,不同软件之间通信的约定。</dd>
<dt>CDN</dt>
<dd>内容分发网络,将静态资源缓存到离用户最近的服务器节点。</dd>
<dt>ORM</dt>
<dd>对象关系映射,将数据库表映射为编程语言中的类。</dd>
</dl>
一个 dt 可以配多个 dd:
<dl>
<dt>HTTP 方法</dt>
<dd>GET:请求资源</dd>
<dd>POST:提交数据</dd>
<dd>PUT:更新全部资源</dd>
<dd>DELETE:删除资源</dd>
</dl>
dl 不限制 dd 数量,适合 FAQ、配置项说明、字典释义。
步骤 5:用 CSS 改变列表样式
<style>
.checklist {
list-style-type: none; /* 去掉默认圆点 */
padding-left: 0; /* 去掉默认缩进 */
}
.checklist li::before {
content: "☑ "; /* 自定义符号 */
color: #2ecc71;
}
.square-list {
list-style-type: square; /* 实心方块 */
}
.inside-list {
list-style-position: inside; /* 符号缩进在文本区域内 */
}
</style>
<ul class="checklist">
<li>代码审查</li>
<li>单元测试</li>
<li>文档更新</li>
</ul>
常见 list-style-type:disc(默认实心圆)、circle(空心圆)、square(方块)、decimal(数字)、decimal-leading-zero(01, 02)。
讲清楚要点
- ul 和 ol 是容器,li 是唯一合法子元素:ul/ol 的直接子节点必须是 li,不能在 ul 里直接放 div 或文本。
- 嵌套必须放在 li 内部:
<li>文本<ul>...</ul></li>,不是<li>...</li><ul>...</ul>。 - dl 不是列表的替代品:有 dt/dd 严格对应关系时才用 dl,不要拿它替代 ul 做普通菜单。
- ol 的 type 属性语义化强于 CSS:搜索引擎和无障碍工具可能读取 type;但现代 CSS
list-style-type更灵活,可以指定lower-alpha、cjk-ideographic等。 - 不要拿列表做纯视觉缩进:没内容需要列表语义的纯缩进,用 CSS padding/margin。
你可能会懵的地方
-
ul 里直接放 div 为什么渲染正常但不对? 浏览器会容错,自动修正 DOM,但生成的结构不可控。F12 看 Elements 面板,你会发现 div 被移到了 ul 外面。HTML 规范里 ul 的内容模型只能是 li。
-
嵌套时缩进好深,层数有限制吗? HTML 规范无限制,但超过 4 层人类阅读困难。深层嵌套通常是信息架构没做好,考虑拆成多个列表或折叠面板。
-
ol 和 ul 能互相嵌套吗? 完全可以。ul 里套 ol,ol 里套 ul,取决于子项的语义:比如「前端技术分类」里,技术名用 ul,某个技术的学习步骤用 ol。
-
dl 能嵌套 dl 吗? 可以,但不常见。如果术语本身需要进一步解释,dd 里放嵌套的 dl 是合法的,只是结构会迅速变复杂。
-
为什么 list-style 在 li 上设有时灵有时不灵?
list-style-type继承自 ul/ol,在 li 上直接设置也能生效,但list-style-image和list-style-position的行为在 ul/ol 上设最稳妥。
错法对照
| 错法 | 问题 | 正解 |
|---|---|---|
<ul><div>...</div></ul> | ul 只能直接包含 li | <ul><li><div>...</div></li></ul> |
<li>文本</li><ul>...</ul> | 嵌套 ul 不是 li 的子元素 | <li>文本<ul>...</ul></li> |
用 <br> 硬拼列表 | 无列表语义,屏幕阅读器读不出来 | 用 ul/ol/li |
| ol 做纯视觉编号,内容无顺序 | 语义错误 | 无顺序用 ul |
| dl 里只有 dt 没有 dd | 定义不完整 | 每个 dt 至少配一个 dd |
| 用 list-style 做缩进装饰 | 滥用列表语义 | 无列表内容用 CSS padding |
卡点急救
- 列表符号和文字间距太大/太小:调
padding-left(ul 默认约 40px)或list-style-position: inside。 - 嵌套列表符号层级没变化:浏览器默认 ul 嵌套时,外层 disc → 内层 circle。如要自定义,逐层用类选择器:
.level-1 { list-style: disc; } .level-2 { list-style: circle; }。 - ol 序号想从 0 或负数开始:
start="0"或start="-2"都合法,但负数序号在视觉上可能困惑,谨慎使用。 - 去掉列表样式后左边留白还在:
list-style: none只去符号,ul 默认还有padding-left: 40px,需要显式设padding-left: 0。
面试常问
-
ul 和 ol 的区别? ul 是无序列表(unordered list),项之间无先后关系,默认显示圆点;ol 是有序列表(ordered list),项之间有顺序或排名含义,默认显示数字。两者都直接包含 li 作为列表项。
-
dl/dt/dd 什么时候用? 定义列表(description list)用于「术语-描述」成对出现的内容:FAQ 问答、配置项说明、词汇表。dt 是术语,dd 是解释;一个 dt 可配多个 dd。
-
如何实现自定义列表符号? 两层做法:①
list-style-type改为内置值(square、circle 等);② 彻底自定义用list-style: none配合 li::before { content: "…" },可放图标字体、Emoji、甚至 background-image。 -
列表嵌套有什么规范要求? 嵌套的 ul/ol 必须位于某个 li 元素内部,不能是 ul 的兄弟节点。HTML 解析器会容错修正,但规范写法是保证 DOM 可预期的唯一方式。
自测三问
- 一组「操作步骤」应该用 ul 还是 ol?为什么?
- 写出一个两层嵌套列表的正确 HTML 结构。
- dl 和 ul 的核心语义差异是什么?
小结一句话
列表是结构化信息的骨架:无序列表并列陈列,有序列表强调先后,定义列表成对解释——选对标签,机器和人都能一目了然。
延伸
- MDN:HTML 列表基础
- 下一课:链接——a 标签的 href、target、rel、锚点和下载的正确用法。