ol标签不渲染编号,必须用li包裹每项;漏写li会导致编号错乱或降级为段落;type和start属性兼容性差,推荐用css counters实现稳定可控的编号,并确保ol+li结构完整以保障可访问性。

ol 标签本身不渲染编号,编号由浏览器自动计算生成;直接写 <ol>A</ol> 不会显示 “1. A”,必须用 li 包裹每一项。
为什么 ol 里漏写 li 会导致编号错乱
常见错误是把内容直接塞进 ol,比如:<ol>第一步<br>第二步</ol>。浏览器会把换行和文本当作匿名文本节点处理,li 缺失意味着语义结构断裂——结果常是 “1. 第一步” 后面紧接 “1. 第二步”,或整个列表被降级为普通段落。
- HTML 规范要求
ol的直接子元素只能是li、script或template,其他内容属于“解析异常” - 嵌套时(如
ol里再套ul),也必须确保每层ol/ul内部都由li包裹,不能ol > ul直连 - Vue/React 模板中漏写
li会直接编译报错,不是容错问题,而是语法非法
type 和 start 属性的兼容性现实
type 属性(如 type="a")虽在 HTML 中合法,但仅支持有限值:1、a、A、i、I;像 lower-greek 这类 CSS 值它根本不认。而 start 虽能设起始数字,但若后续手动插入新 li 又忘了调 start,编号就会断层。
- 现代项目应优先用 CSS 的
list-style-type控制编号样式,它支持更多值且可继承、可覆盖 -
start在动态列表中极易失效:JS 插入新li后,浏览器不会重算编号逻辑,旧编号仍按初始start推进 - 想实现“接续上一列表”,更可靠的做法是用 CSS counters,而非依赖
start
用 CSS 替代 type 实现稳定编号控制
直接改 ol 的 type 属性看似简单,但跨浏览器行为不一致(尤其 Safari 对 type="I" 的罗马数字渲染有偏差),且无法做条件编号(如奇数项加粗、偶数项缩进)。
- 清掉默认样式:
ol { list-style: none; } - 启用计数器:
ol { counter-reset: step; }+li::before { counter-increment: step; content: counter(step) ". "; } - 这样编号完全由 CSS 控制,JS 动态增删
li后无需干预,浏览器自动重排 - 若需字母编号,把
counter(step)换成counter(step, lower-alpha)即可,比type="a"更可控
真正容易被忽略的点是:编号是否需要语义化参与可访问性。屏幕阅读器会读出“列表,共 5 项,第 2 项”,这个信息来自 ol+li 结构本身,而不是你写的 1. 或 CSS 伪元素。所以哪怕全用 CSS 重绘编号,li 一个都不能少,ol 的语义容器作用不可替代。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











