子列表必须嵌套在父级li内,否则浏览器会强制闭合父ol导致编号重置;html规范要求ol/ul只能作为li的子元素;跨ol连续编号需用css counter实现。

ol 嵌套时编号重置(如第二级总从 A 或 1 开始)不是浏览器缺陷,而是 DOM 结构非法导致的必然结果。只要子 ol 没被包在父 li 里,浏览器就会强制闭合前一个列表、新建一个——计数器自然归零。
子列表必须嵌套在 li 内部,不能并列在 ol 外
这是所有编号中断问题的根源。HTML 规范明确要求:ol 和 ul 只能作为 li 的子元素出现,不能直接跟在另一个 li 后面、平级置于同一父 ol 中。
- ❌ 错误写法(
ol悬空在li外):<ol type="A"> <li>A. First item</li> </ol><ol type="1"> <!-- ❌ 独立标签,脱离上下文 --><li>1. Sub-item</li> </ol>
- ✅ 正确写法(子
ol是li的直接子节点):<ol type="A"> <li>A. First item <ol type="1"> <li>1. Sub-item</li> </ol> </li> </ol> - 如果内容是段落或标题(非纯列表项),仍需用
li包裹——哪怕它看起来像一个章节标题 - 移除包裹用的
div或p:它们会切断嵌套链,让子ol“掉出”语义层级
start 属性只接受整数,且仅控制“从几开始数”
start 不是“显示第几个字母”,而是阿拉伯数字意义上的起始计数值。它和 type 配合生效,但本身不决定样式。
-
start="3"+type="a"→ 显示为 c.(因为 a=1, b=2, c=3) -
start="3"+type="i"→ 显示为 iii.,不是“第三个罗马数字字符” -
start="abc"或start="5.8"会被静默转成start="1",不报错也不警告 - 动态 JS 修改
ol.start = 100会导致视觉跳变,但屏幕阅读器可能仍读旧序号——可访问性受损
跨多个 ol 连续编号必须用 CSS counter
原生 start 只作用于单个 ol,无法跨容器延续。比如法规文档中“第34条”后接“第35条”,但中间插入了带子条款的独立 ol,此时 start 就无能为力。
- 用
counter-reset在外层容器初始化计数器:section { counter-reset: clause; } - 每个主条款用
counter-increment: clause,并通过::before输出:clause::before { content: counter(clause) ". "; } - 子级计数器需分层定义(如
counter-reset: subclause在li上),避免污染全局 - 此时可安全移除所有
ol的list-style,完全交由 CSS 控制——语义与样式解耦
真正难的不是写对 type="a",而是意识到:只要子 ol 没被 li 包住,就永远得不到连续编号;而一旦结构合法,start 和 type 就只是参数微调。CSS counter 是补救结构限制的最后手段,不是首选方案。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











