ol 用于表达有明确先后顺序、步骤依赖或计数意义的内容,必须直接包含 li 子元素,禁止嵌套 div;应避免 type/start 属性,优先用 CSS counter 实现编号;嵌套需语义合理且不超过两层。

ol 列表不是“带数字的 ul”,它的语义是表达**有明确先后顺序、步骤依赖或计数意义**的内容。直接套用 ul 的写法,或者只图数字显示而忽略结构,会导致可访问性断裂、SEO 降权、屏幕阅读器读错顺序,甚至影响后续 CSS 计数逻辑(比如用 counter-reset 自定义编号时)。
ol 必须由 li 直接子元素构成,不能嵌套 div 或 p 作为列表项容器
常见错误是把 li 当成“装饰壳”,往里面塞一个 div 再放内容:
<ol> <li><div class="step">打开电源</div></li> <li><div class="step">按下启动键</div></li> </ol>
这会让屏幕阅读器把整个 div 当作一个不可拆分的“块”,丢失语义层级;CSS 伪元素(如 ::marker)也可能失效。正确写法是让语义内容直接落在 li 里:
-
li可以直接包含文本、p、h3、img、code等任何合法的流内容元素 - 如果需要分段,用
p或h3,而不是div - 避免给
li加role="listitem"—— 它本来就是listitem,加了反而可能干扰辅助技术
type 和 start 属性要慎用,优先靠 CSS 控制编号样式
type(如 type="A"、type="i")和 start 是 HTML4 遗留属性,在现代项目中容易引发兼容问题:Safari 对 type="I"(大写罗马数字)支持不一致;start 在嵌套 ol 中行为不可靠;且它们无法实现“第 1 步:”“Step 2:”这类带前缀的编号。
更可靠的做法是关掉原生编号,用 CSS 重置:
实现 Markdown↔ HTML 互转,支持导出 PDF,用于用户请求的文档格式转换。
ol {
list-style: none;
counter-reset: step;
}
ol li {
counter-increment: step;
}
ol li::before {
content: "第 " counter(step) " 步:";
font-weight: bold;
}
- 所有浏览器对
counter支持良好(IE9+) - 可自由组合文字、符号、图标(用
url()引入 SVG) - 避免因
type值拼写错误(如type="1"实际无效)导致回退到默认阿拉伯数字
嵌套 ol 时必须保持语义连贯,避免“步骤里的步骤”滥用
嵌套本身合法,但常见误用是把“子操作”硬塞进第二层 ol,结果变成:
<ol>
<li>配置网络</li>
<li>安装依赖</li>
<li>启动服务
<ol>
<li>检查端口占用</li>
<li>加载配置文件</li>
<li>初始化数据库连接</li>
</ol>
</li>
</ol>
问题在于:第三步的三个子项并不是“并列于前两步之后的第 4、5、6 步”,而是“第 3 步内部的执行环节”。此时应考虑是否该用 ul(无序子任务)或 dl(定义型流程),而非强制嵌套 ol。只有当子项本身具备独立、不可交换的次序(例如“先连数据库,再加载配置,最后启动监听”),嵌套才成立。
- 嵌套层级建议不超过 2 层,超过后可读性和维护性陡降
- 每层
ol应有明确的上下文说明(比如用h3标题描述当前阶段) - 不要为“视觉缩进”而嵌套 —— 缩进应该用 CSS
padding-left实现
真正难的不是写出能显示数字的 ol,而是判断某段内容到底“是否值得用 ol”。一个没被想清楚的 ol,比写错一个属性更难修复 —— 因为它会把语义污染带到 DOM 结构最底层。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










