修改ol.start属性后编号不更新,需强制重排(如读offsetheight)或替换节点;连续编号应使用css计数器而非多个start;嵌套列表必须语义正确;动态增删须操作dom而非仅样式,否则破坏可访问性。

直接改 start 属性或用 JavaScript 重设 ol.start,多数情况下编号不会实时更新——浏览器不自动重排,视觉和可访问性都可能出错。
修改 start 后列表没变化?必须触发重排
DOM 上改了 ol.start = 100 或通过 setAttribute('start', '100'),但页面编号仍显示旧值,是因为 CSS 计数逻辑未刷新。浏览器把编号渲染当作“一次性计算”,不监听 start 变化。
- 最轻量办法:读一次
offsetHeight强制重排,例如ol.offsetHeight; // 触发 layout - 更稳妥做法:替换整个
<ol></ol>节点,比如用ol.replaceWith(newOl) - React/Vue 中,仅靠 state 更新
start不够,必须让<ol></ol>节点被完整卸载再挂载(比如加 key 变化)
多个 <ol></ol> 要连续编号?start 不行,得用 CSS 计数器
比如文档分两段,第一段末尾是「7.」,第二段开头要接「8.」,这时不能靠两个独立的 <ol start="8"></ol>——因为它们语义隔离,屏幕阅读器会分别报“列表 1 / 共 3 项”“列表 2 / 共 5 项”,且打印时可能断开。
- 统一用一个计数器名,如
counter-reset: section;放在父容器上 - 每个
<ol></ol>内部的<li>都加counter-increment: section; -
li::before { content: counter(section) ". "; }确保视觉连续 - 注意:如果中间删了某段
<ol></ol>,编号不会自动收缩,需手动重置计数器或重绘整块
嵌套列表编号中断(比如 B. 后还是 A.)?结构错了
这不是样式问题,是 HTML 嵌套违反规范导致浏览器重置计数器。子 <ol></ol> 必须作为父 <li> 的**直接子元素**,不能放在 <li> 外面、也不能塞进 <p></p> 或 <div> 里。
<ul>
<li>❌ 错误:<code><ol type="A"><li>A.</li></ol>
<ol type="1"><li>1.</li></ol> —— 两个 <ol></ol> 并列,第二个被当全新列表
<ol type="A"><li>A.<ol type="1"><li>1.</li></ol>
</li></ol>
<ol></ol> 包在 <li> 内,哪怕只用一个空 <span></span> 占位也比脱离结构强动态增删列表项后编号乱了?别依赖 value 属性
<li value="5"> 是过时方案,W3C 明确建议避免。它只覆盖单个项,后续项仍按前一项 +1 算,极易造成跳跃、重复、倒退,且屏幕阅读器常忽略其语义。
- 新增项:用 CSS 计数器 +
counter-increment,天然按顺序递增 - 删除项:不要只
display: none,而是从 DOM 移除;否则计数器不会跳过该位置,编号会卡住 - 真要保留 DOM 节点(比如做动画),就得手动重置父级
counter-reset,再重新触发所有可见项的counter-increment
最易被忽略的一点:可访问性工具(如屏幕阅读器)完全不看 start 或 CSS 计数器生成的编号,它们只按 DOM 顺序读“第1项、第2项……”。如果视觉编号和 DOM 顺序不一致(比如删了中间项又没重排),残障用户听到的序号就和看到的对不上——这不是样式问题,是语义断裂。











