ol标签必须显式闭合且仅含li子元素,禁止混入其他标签;type和start属性已废弃,应改用CSS counters实现编号控制。

ol标签必须显式闭合,不能省略
HTML5解析器虽会自动补全未闭合的 ,但实际开发中漏写闭合标签极易引发DOM结构错乱——尤其嵌套时,浏览器可能把后续所有内容都当作上层 <li> 的文本子节点处理,导致JS获取 children 或样式应用完全失效。
常见错误现象:<ol>
<li>第一步</li>
<ol><li>子步骤</li></ol>
</ol>(缺 )→ 子 <ol></ol> 被识别为“第一步”的内容,而非嵌套列表。
- 所有
<ol></ol>必须配对出现:<ol>...</ol>,不可依赖自动修复 - 嵌套时,内层
<ol></ol>闭合后,外层仍需独立闭合 - 验证工具(如W3C Validator)会直接报错
End tag for “ol” seen, but there were open elements
ol内部只能直接包含li,不能混入其他标签
<ol></ol> 是严格的内容模型:它的直接子元素只能是 <li>。插入 <p></p>、<div>、<code><h3></h3> 甚至注释都会破坏语义,部分浏览器降级渲染时可能丢弃非法子节点,或导致无障碍阅读器跳过整段列表。
使用场景:想在某个步骤前加说明文字?正确做法是把说明放进对应 <li> 内,而不是放在 <ol></ol> 和 <li> 之间。
立即学习“前端免费学习笔记(深入)”;
- ✅ 合法:
<ol><li> <strong>注意</strong>:先备份数据</li></ol> - ❌ 非法:
<ol> <p>请按顺序操作:</p><div class="aritcle_card flexRow"> <div class="artcardd flexRow"> <a class="aritcle_card_img" href="/xiazai/skill10246" title="HTML Text Extract"><img src="https://img.php.cn/upload/skill/001/246/273/6adaf20dee630206.jpg" alt="HTML Text Extract" ></a> <div class="aritcle_card_info flexColumn"> <a href="/xiazai/skill10246" title="HTML Text Extract">HTML Text Extract</a> <p>从HTML页面(URL、文件或标准输入)中提取主体内容文本,去除导航、页脚、广告和模板文本。可直接传递给readability_check或其他文本工具。</p> </div> <a href="/xiazai/skill10246" title="HTML Text Extract" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div> <li>第一步</li> </ol> - 若需分组标题,用
<section></section>+<h3></h3>包裹整个<ol></ol>,而非塞进<ol></ol>内部
type和start属性在HTML5中已废弃,别再用了
虽然部分浏览器仍支持 <ol type="a" start="3"></ol>,但HTML5规范明确将其标记为废弃(obsolete)。继续使用会导致验证失败,且无法保证未来兼容性;更重要的是,它绕过了CSS控制权,让样式与结构耦合,违背现代前端分离原则。
性能与可维护性影响:硬编码编号类型会让多语言切换、暗色模式适配、动态重排序等需求变得极其脆弱。
- 替代方案统一用CSS:
ol { list-style-type: lower-alpha; counter-reset: section 2; } - 需要自定义起始值?用
counter-increment+::before伪元素更可控 - 旧项目迁移时,全局搜索
type=和start=并替换,比后期调试语义断裂更省力
嵌套ol时,编号逻辑不自动继承,需手动控制
嵌套的 <ol></ol> 默认仍是阿拉伯数字1开始,不会延续外层编号(比如外层是“3. 操作步骤”,内层不会自动变成“3.1”)。这不是bug,而是设计使然——每层 <ol></ol> 是独立计数上下文。
容易踩的坑:以为写个 <ol><li><ol><li>...</li></ol></li></ol> 就能生成层级编号,结果全是“1.”“1.”“1.”。
- 实现“3.1”“3.2”效果,必须用CSS counters:
ol { counter-reset: item; } li { counter-increment: item; } li::before { content: counters(item, ".") ". "; } - 避免用JS遍历DOM去拼接编号,既慢又难维护
- 若仅需视觉缩进而无编号需求,考虑用
list-style: none+ 自定义图标或空格对齐
真正麻烦的不是语法本身,而是当 <ol></ol> 出现在表单验证提示、文档导出PDF、或被屏幕阅读器逐项播报时,一个没闭合的标签或非法子元素,会让整个信息流崩掉——而这种问题往往在线上环境才暴露。


















