HTML原生<ol>不支持跨多个<ol>自动接续序号,必须用start属性手动指定或CSS计数器实现;前者简单但易出错,后者灵活但需注意无障碍语义。

HTML有序列表跨段落接续序号的原生方案
HTML原生<ol>不支持自动跨多个独立<ol>元素接续序号——每个<ol>都是全新计数起点。想让“第一段末尾是3.”、“第二段开头是4.”,不能靠默认行为,得手动干预。
可行路径只有两条:用start属性硬指定起始值,或用CSS计数器(counter-reset/counter-increment)接管编号逻辑。前者简单但脆弱,后者灵活但需注意作用域。
用start属性手动对齐序号
这是最直接的办法,适合内容稳定、段落数量固定的场景。你得自己算好每个<ol>该从几开始。
比如第一段有3项,第二段想从4开始,就写:
<ol> <li>第一项</li> <li>第二项</li> <li>第三项</li> </ol> <p>中间穿插一段说明文字</p> <ol start="4"> <li>第四项</li> <li>第五项</li> </ol>
常见错误:
- 把
start写成字符串如start="four"——必须是整数 - 没数清前一个
<ol>实际有多少<li>(含嵌套里的),导致跳号或重复 - 后续增删前面列表项后,忘记同步改后面的
start值
CSS计数器实现真正连续编号
用counter-reset和counter-increment可以绕过HTML结构限制,让编号按DOM顺序自然延续,哪怕<li>分散在不同<ol>甚至<div>里。
关键点:
立即学习“前端免费学习笔记(深入)”;
- 在外层容器(比如
<article>)设counter-reset: item - 所有需要编号的元素用
counter-increment: item - 用
::before伪元素+counter(item)显示数字
示例:
<article style="counter-reset: item;">
<ol>
<li style="counter-increment: item;"><span style="counter-increment: none;">第一项</span></li>
<li style="counter-increment: item;"><span>第二项</span></li>
</ol>
<p>中间段落</p>
<ol>
<li style="counter-increment: item;"><span>第三项</span></li>
</ol>
</article>
<style>
li::before {
content: counter(item) ". ";
}
</style>
注意:<li>本身会触发计数,如果还给它加counter-increment,就会多加一次。所以上面示例中用<span>包裹内容,并确保<li>只负责计数、不重复渲染编号。
为什么不用JavaScript动态算start
有人想用JS遍历前面所有<li>再设start,但问题不少:
常见陷阱:
- 页面未加载完成时运行,
document.querySelectorAll('li')漏掉动态插入的项 - 服务端渲染(SSR)或静态站点生成(SSG)环境下,JS还没执行,HTML已输出,序号错乱
- 用户禁用JS,整个编号系统失效
- SEO不友好——搜索引擎看到的是无序号的原始
<li>,缺乏语义
除非你明确控制所有渲染时机且能保证JS必执行,否则优先选CSS计数器或静态start。真正的难点不在怎么写,而在编号语义是否要被辅助技术(如读屏器)识别——CSS生成的内容默认不进无障碍树,这点常被忽略。



















