子列表必须嵌套在<li>内而非</ol>外,否则成为独立列表导致编号重置;HTML原生type属性不继承前缀,需用CSS counters()实现2.1式编号,且语义结构错误会使CSS失效。

子列表必须写在 <li> 里面,不能写在 </ol> 外面
浏览器只认 HTML 结构嵌套,不看缩进或 CSS 样式。如果你把第二个 <ol> 放在父 </ol> 之后,它就变成全新列表,编号必然重置为 1 或 A。
- 错误写法:
<ol type="A"><li>A. Item</li></ol><ol type="1"><li>1. Sub-item</li></ol>→ 第二个<ol>是独立节点,和上一级毫无关系 - 正确写法:子
<ol>必须是某个<li>的直接子内容,例如<li>A. Item<ol type="1"><li>1. Sub-item</li></ol></li> - 验证方法:右键 → “检查”,确认子
<ol>确实包裹在<li>内部,而不是和<li>并列或在</ol>之外
type 属性控制编号类型,但层级间不自动继承前缀
HTML 原生 <ol> 的 type(如 "A"、"1"、"a")只决定本层显示格式,不会拼接父级编号(比如不会自动生成 2.1)。它只是“重置式编号”。
- 外层用
type="A"→ 显示 A.、B.、C. - 内层用
type="1"→ 显示 1.、2.、3.(永远从 1 开始,不管外层是 B 还是 C) - 若需要 2.1、2.2 这类带前缀的编号,必须用 CSS
counters(),不能只靠type -
start属性只影响本层起始值(如start="3"→ 从 3 开始),对子层无传递作用
用 counters(list-item, ".") 实现 2.1、2.2 这类自动拼接编号
浏览器内置 list-item 计数器会随嵌套层级自动累积,配合 counters() 函数就能输出带分隔符的多级编号,无需手动声明 counter-reset。
- 关键 CSS:
ol ol li::before { content: counters(list-item, ".") " "; } - 必须先清除默认样式:
ol { list-style-type: none; },否则原生编号和伪元素冲突 - 外层
<ol start="2">+ 内层嵌套<ol>→ 自动产生 2.1、2.2、2.3 - 注意:这个方案依赖浏览器对
list-item的原生支持,IE 不支持counters(),需降级处理
常见视觉错位问题:子列表缩进和对齐要单独调
嵌套后子 <ol> 默认有 padding-left,但常和文本内容不对齐,尤其当父 <li> 含大段文字时。
立即学习“前端免费学习笔记(深入)”;
- 推荐显式控制:
ol ol { padding-left: 0; margin-left: 1.5em; } - 编号前缀对齐用
display: inline-block+width,例如:ol ol li::before { display: inline-block; width: 3em; } - 避免用
text-indent或负margin调整编号位置——容易在打印或高对比度模式下失效 - 如果子列表项文字换行后悬垂缩进不一致,加
ol ol li { margin-bottom: 0.4em; }统一行距
<ol> 没包在 <li> 里),后续所有 CSS 编号逻辑都建立在错误 DOM 上,再复杂的 counters() 规则也救不回来。



















