<ol> 标签天然支持商品排行榜,具备自动编号、无障碍友好、SEO 优化等优势;应避免用 <div>+CSS 模拟序号,推荐用 ::marker 自定义样式,动态更新无需手动维护序号,兼容旧浏览器时可回退 CSS 计数器方案。

ol 标签本身就能做商品排行榜,不需要额外 hack
HTML 的 <ol> 天然支持自动编号、起始值、倒序、自定义类型(type="A"、type="i"),直接用它渲染排行榜最干净——浏览器原生语义化,无障碍友好,SEO 友好,也不依赖 JS。
常见误区是强行用 <div> + CSS 计数器模拟序号,结果丢失语义、屏幕阅读器读不出排名、打印时序号消失。
-
<ol>默认从 1 开始,用start="1"显式声明更稳妥(尤其动态插入时防错) - 商品名用
<li>包裹,内部可自由嵌套图片、价格、评分等 HTML 片段 - 别在
<li>里手动写 “第1名”“第2名”——交给<ol>渲染,后期改顺序或加条目不需手动修文本
怎么让 ol 的数字样式匹配设计稿(比如带底色圆圈、右对齐)
CSS 可以完全接管 <ol> 的标记外观,但要注意:修改 list-style 后,原生序号会消失,必须用 ::marker 伪元素重绘——这是现代方案,兼容性需查 ::marker 支持情况(Chrome 89+、Firefox 86+、Safari 15.4+)。
例如给数字加橙色圆圈、右对齐:
立即学习“前端免费学习笔记(深入)”;
ol.rankings {
counter-reset: ranking;
}
ol.rankings li {
position: relative;
padding-left: 40px;
}
ol.rankings li::marker {
content: counter(ranking);
counter-increment: ranking;
display: inline-block;
width: 24px;
height: 24px;
background: #ff6b35;
color: white;
border-radius: 50%;
text-align: center;
line-height: 24px;
font-size: 14px;
margin-right: 12px;
}
⚠️ 注意:list-style: none + ::marker 是绑定关系,只设 list-style: none 而不提供 ::marker 会导致序号彻底消失。
需要动态更新排名(比如 AJAX 刷新后重排)怎么办
DOM 操作时,<ol> 的序号会自动重算,无需 JS 手动更新数字文本——这是最大优势。但有两点要小心:
- 用
innerHTML替换整个<ol>内容没问题;但若用appendChild或insertBefore增删<li>,确保操作的是同一个<ol>实例,否则计数器可能断掉 - 如果用框架(React/Vue),别把
key设成序号(如key={index}),否则排序变化时 DOM 复用逻辑会错乱;应使用商品 ID 作key - 服务端返回数据已按排名排序?前端就老老实实
map()渲染<li>,别再用 JS 算一遍序号塞进文本
IE11 或旧版 Safari 必须兼容时的降级方案
::marker 不可用,就得回退到 CSS 计数器 + content,但必须禁用原生标记:
ol.rankings {
list-style: none;
counter-reset: ranking;
}
ol.rankings li {
counter-increment: ranking;
}
ol.rankings li::before {
content: counter(ranking) ".";
display: inline-block;
width: 2em;
margin-right: 0.5em;
text-align: right;
}
⚠️ 这里 content: counter(ranking) "." 的顿号是中文全角,避免和英文句点混淆;同时 counter-reset 必须写在 <ol> 上,不能写在 <li> 上,否则每个 <li> 都重置计数器。
真正麻烦的不是写法,而是当排行榜需要语音播报、打印 PDF 或被爬虫解析时,CSS 生成的内容不会进入 DOM 文本流——这时候还是得靠原生 <ol>,哪怕样式妥协一点。



















