子列表必须嵌套在内而非顶层,否则html非法;子可设type和start独立控制编号,css建议用padding-left和margin-top统一缩进与间距,无障碍依赖正确dom嵌套。

子列表必须嵌套在 <li> 里,不能直接放在 <ol></ol> 中
HTML 的有序列表(<ol></ol>)本身不支持“层级”概念,所谓“子级列表”,本质是把另一个 <ol></ol> 或 <ul></ul> 放进某个 <li> 的内容中。浏览器会自动渲染为缩进的嵌套结构。
常见错误是把子 <ol></ol> 写在父 <ol></ol> 的顶层,比如:
<ol> <li>第一项</li> <ol><li>子项1</li></ol> <!-- ❌ 错误:不在任何 <li> 内 --> </ol>
这样会导致 HTML 结构非法,解析结果不可控(多数浏览器会自动闭合父 <ol></ol>,造成意外断开)。
- 正确写法:子列表必须是
<li>的直接子元素之一(可跟文本、其他标签并存) - 子列表可以是
<ol></ol>(继续编号)或<ul></ul>(换为圆点),取决于语义需求 - 嵌套深度没有硬性限制,但超过 3 层易影响可读性和辅助技术支持
start 和 type 属性对子 <ol></ol> 独立生效
子级 <ol></ol> 的编号起始值和样式不受父列表控制,需单独设置。例如让子列表从 (a) 开始、或从数字 5 继续,都要显式声明。
示例:
<ol>
<li>主任务一</li>
<li>主任务二
<ol type="a">
<li>子步骤 a</li>
<li>子步骤 b</li>
</ol>
</li>
<li>主任务三
<ol start="5">
<li>从 5 开始编号</li>
</ol>
</li>
</ol>
-
type可取值:"1"(默认)、"a"、"A"、"i"、"I" -
start接受整数,注意它设置的是「第一个<li>显示的序号」,不是偏移量 - CSS 的
counter-reset/counter-increment能实现更灵活的编号逻辑,但原生属性更轻量、兼容性更好
用 CSS 控制缩进和间距比依赖默认样式更可靠
不同浏览器对嵌套列表的默认缩进和行高略有差异,尤其在混合使用 <ol></ol> 和 <ul></ul> 时。若需视觉统一,建议用 CSS 显式控制。
关键样式点:
- 用
margin-left或padding-left调整子列表整体缩进(推荐用padding-left避免外边距折叠) - 对子
<ol></ol>设置margin-top: 0消除与父<li>文本之间的额外空隙 - 如需重置编号颜色/字体大小,直接选中子
<ol></ol>下的<li>,而非整个<ol></ol>
简单示例:
ol ol {
padding-left: 1.5em;
margin-top: 0;
}
ol ol li {
font-size: 0.9em;
color: #555;
}
无障碍支持依赖正确的嵌套结构,而非 CSS 视觉效果
屏幕阅读器通过 DOM 层级识别列表嵌套关系。只要子 <ol></ol> 在 <li> 内,就会被读作“子列表”,即使你用 CSS 把它显示成 inline 或取消缩进。
但以下情况会破坏语义:
- 用
<div> 模拟列表项,再靠 CSS 画序号(丢失 <code><li>角色) - 子列表放在
<li>外,靠绝对定位“看起来像嵌套” - 忘记闭合
验证方式:用浏览器开发者工具检查 DOM 树,确认子 <ol></ol> 是某个 <li> 的子节点,且没有孤立的 <ol></ol> 元素游离在外。
嵌套本身不难,难的是保持结构干净——多一层嵌套,就多一分维护成本和出错可能。实际项目中,优先考虑是否真需要多层编号,有时用段落标题 + 简单分隔线反而更清晰。











