有序列表起始值应使用 <ol> 的 start 属性而非 <li> 的 value;start 设定全局起始编号(整数),value 仅覆盖当前项并重置后续递增起点;CSS counter-reset 可替代但更复杂,服务端需校验 start 值为整数以防注入。

有序列表起始值用 start 属性,不是 value
很多人想让 <ol> 从 5 开始编号,却去给 <li> 加 value="5",结果只影响当前项、后续仍从 1 接续——这是常见误解。value 是单个 <li> 的覆盖值,而全局起始要用 <ol> 的 start 属性。
正确写法很简单:
<ol start="5"> <li>第五项</li> <li>第六项</li> </ol>
渲染结果就是 5. 第五项,6. 第六项。注意:start 值必须是整数(正负皆可),浏览器会自动向下递增,不支持小数或字母。
start 和 value 混用时的编号逻辑
当 <ol start="3"> 里某个 <li value="8"> 出现,编号会跳变,之后项继续按 8 递增,而不是回到 start 的节奏。
立即学习“前端免费学习笔记(深入)”;
例如:
<ol start="3"> <li>三项</li> <!-- 显示 3. --> <li value="8">八项</li> <!-- 显示 8. --> <li>九项</li> <!-- 显示 9.,不是 4. --> </ol>
-
start只作用于第一个<li>(除非被value覆盖) -
value重置当前项编号,并影响后续自动编号起点 - 混合使用容易导致序号断裂,调试时建议优先用
start,仅在特殊项需要跳号时才加value
CSS counter-reset 能替代 start 吗?
能,但没必要为简单起始值绕路。CSS 方案适合动态控制或复杂嵌套场景,比如多级列表中子列表继承父级编号。
纯起始值设置,直接用 start 更轻量、语义清晰、无需额外样式:
<ol start="100"> <li>第一百条</li> </ol>
若真要用 CSS:
ol.custom { counter-reset: list-item 99; }<br>ol.custom li { counter-increment: list-item; }<br>ol.custom li::before { content: counter(list-item) ". "; }注意:counter-reset 的值比期望首个编号小 1(如要从 100 开始,设为 99),且需手动加 ::before 才显示数字——HTML 原生 start 自动处理这些。
服务端渲染或模板引擎里拼 start 要防注入
如果 start 值来自用户输入或变量(比如分页列表的当前页偏移),必须校验是否为整数,否则可能破坏 HTML 结构或引发 XSS。
- Node.js / Express 中建议:
parseInt(input, 10)+isNaN()判断 - Python Jinja2 中用
{{ start|int }}过滤,但需确保传入前已校验范围 - 禁止直接插字符串:
<ol start="{{ user_input }}">是危险的
浏览器对非法 start 值(如 start="abc")通常降级为 1,但不可依赖——校验应在服务端完成。



















