移动端 counter 序号不显示或错位,主因是 safari 等浏览器对伪元素渲染敏感,易受缩放、flex 布局影响;修复需确保 counter-reset 在容器上、li 为 block、::before 加 white-space: nowrap 和 user-select: none。

移动端用 counter 时为什么序号不显示或错位
根本原因是移动端浏览器(尤其是 Safari 和旧版 Chrome)对伪元素渲染更敏感,::before 容易被 user-scalable=no、缩放干预或 flex 布局挤压导致不可见。常见现象是编号全为 “0”、只显示第一项、或多行文本时序号和文字错开。
关键修复点:
-
counter-reset必须写在容器上(如ol或.list),不能写在li上——否则每项都重置为 1 - 确保
li是块级元素(display: block),避免被inline或flex子项干扰计数作用域 - 给
li::before加white-space: nowrap,防止 iOS Safari 把 “1.” 拆成两行 - 禁用用户选中序号:
user-select: none,否则长按可能触发复制或光标错位
如何让自定义序号在小屏上对齐且不挤内容
原生 ol 的 padding-left 在不同设备上差异大,用 counter 时必须手动控制留白。直接用 margin-left 推文字容易在多行时第二行顶到序号下方。
推荐做法:
- 给
li设position: relative -
li::before用position: absolute; left: 0; width: 2em; text-align: right - 再给
li加padding-left: 2.5em(略大于width,留出空隙) - 避免用
flex包裹li—— 它会破坏::before的定位上下文,改用display: block+margin
嵌套列表在 iOS 上编号串行或跳号怎么办
问题本质是 counters() 在 Safari 中对作用域判断更严格:如果子列表没显式 counter-reset,它不会自动继承父级重置逻辑,而是继续累加。
实操写法(兼容 iOS 15+ 和 Android Chrome):
ol {
counter-reset: section;
}
ol ol {
counter-reset: subsection; /* 必须显式重置,不能省 */
}
li {
counter-increment: section;
}
li ol li {
counter-increment: subsection;
}
li::before {
content: counter(section) ". ";
}
li ol li::before {
content: counter(section) "." counter(subsection) " ";
}
注意:counters(section, ".") 在部分旧版 Safari 里会失效,优先用 counter() 显式拼接。
要不要用 @counter-style 替代 counter()?
别在移动端用。@counter-style 虽然能定义图标、前缀、补零等,但 Safari 直到 iOS 16.4 才开始支持,Android Chrome 支持也不稳定。目前仍建议用 content: "Step " counter(step) ":" 这种硬编码方式。
真正容易被忽略的点:
-
counter-reset: step 0和counter-reset: step效果一样,但若想从 “2” 开始,得写counter-reset: step 1(初始值 = 显示值 - 1) - 隐藏的
li(display: none)仍会触发counter-increment,如需跳过,改用visibility: hidden+height: 0 - 微信内置浏览器(X5 内核)不支持
counters(),嵌套场景必须降级为单层counter()+ 手动 class 控制
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











