用ol实现语义正确且可访问的序号列表是唯一推荐方式,因其确保屏幕阅读器、搜索引擎和CSS计数器能正确识别层级与顺序,避免手写span或div导致的无障碍失效与维护成本。

用 ol 实现语义正确且可访问的序号列表
直接用 ol(ordered list)是唯一推荐方式,不是为了“看起来有数字”,而是让屏幕阅读器、搜索引擎和 CSS 计数器都能正确识别层级与顺序。手写 <span>1.</span> 或用 div + 数字文本,会破坏语义,导致无障碍失效,也增加后期维护成本。
关键点:
-
ol默认从 1 开始,无需额外设置start属性,除非要跳过前几条(比如只显示 Top 5 中的第 3–7 名) - 每个榜单项必须用
li包裹,不能用p或div替代 - 如果榜单需要「并列第2名」,
ol本身不支持重复序号,得靠 CSScounter-reset+counter-increment手动控制,但这是少数场景,先别绕进去
用 CSS 自定义序号样式(去掉默认小数点、加图标、对齐)
浏览器默认的 ol 序号带英文句点(如 1.),而高分榜常需 1)、① 或带徽章图标。这时不能删掉 ol,而该用 CSS 覆盖:
ol.rank-list {
list-style-type: none;
counter-reset: rank;
}
ol.rank-list li {
counter-increment: rank;
}
ol.rank-list li::before {
content: counter(rank) ")";
margin-right: 8px;
font-weight: bold;
}
注意:
立即学习“前端免费学习笔记(深入)”;
-
list-style-type: none必须设,否则原生序号和伪元素会重叠 -
counter-reset要写在ol上,不是li;counter-increment写在li上 - 若想用 Unicode 圈数字(①②③),可改用
content: counters(rank, "①②③④⑤⑥⑦⑧⑨⑩");,但超出 10 会回退为阿拉伯数字,不推荐用于长榜单
动态插入榜单时,避免手动拼接 HTML 字符串
如果榜单数据来自 JS 变量或 API,别用字符串模板硬拼 "<li>" + title + "</li>"——容易 XSS,也难维护序号逻辑。应直接操作 DOM 或用现代方法:
推荐做法:
- 用
document.createElement("li")+textContent插入内容(防 XSS) - 用
ol.append(...items)批量追加,比循环appendChild更快 - 如果用框架(如 React/Vue),序号交给组件状态或索引变量(
index + 1),不要塞进 HTML 字符串里 - 切忌在
innerHTML中写"<ol start='"+offset+"'>"</ol>——start属性仅影响初始渲染,JS 动态增删后不会自动重算
移动端适配和性能细节容易被忽略
榜单常出现在信息流中,滚动频繁,但很多人忘了 ol 在 iOS Safari 下有轻微重排问题,尤其配合动画或字体加载时:
- 给
ol加contain: content可减少重绘范围(兼容性查 CanIUse,iOS 15.4+ 支持) - 序号文字别用
font-family: "PingFang SC", sans-serif这类系统字体链——中文标点宽度不一,会导致::before内容左右晃动;统一用等宽字体或设font-variant-numeric: tabular-nums - 如果榜单超过 50 条,考虑虚拟滚动,而不是一次性渲染全部
li——ol本身无性能问题,但大量 DOM 节点会拖慢首屏
序号本质是结构信息,不是装饰。写错一次,后续加筛选、导出 Excel、做 SSR 渲染时都会多一层转换负担。



















