Less无法定义CSS counter变量,只能通过mixin生成counter-reset、counter-increment和content规则;需避免content中非法拼接,兼容性差时应采用硬编码序号备选方案。

Less里不能直接定义CSS counter变量
Less本身不支持声明counter这类CSS运行时计数器变量——它只是CSS预处理器,所有counter()、counters()函数都必须原样输出到编译后的CSS中,由浏览器在渲染时计算。你写的@counter: 1;之类在Less里只是普通变量,和CSS计数器无关。
所以关键不是“在Less里创建counter”,而是“用Less更安全、可维护地生成带counter-increment/counter-reset的CSS规则”。
给ol/ul加自定义序号样式要写三组规则
哪怕只是把数字换成「❶❷❸」,也必须同时控制:counter-reset初始化、counter-increment递增、::marker或::before内容替换。漏掉任意一个,序号就消失或重叠。
推荐用Less mixin封装,避免重复写三行:
立即学习“前端免费学习笔记(深入)”;
.custom-counter(@name: item, @start: 1, @style: decimal) {
counter-reset: ~"@{name}" @start;
> li {
counter-increment: ~"@{name}";
&::marker {
content: counter(@name, @style);
}
}
}
调用:.custom-counter(item, 1, circled-decimal);(注意circled-decimal需浏览器支持,不支持时会回退为decimal)
用::before模拟序号时,content里不能拼接字符串和counter
常见错误是写content: "Step " counter(step);——这在CSS里非法。CSS的content值中,字符串和counter()必须用空格隔开,且不能有+号或插值符号。
正确写法只有两种:
-
content: "Step " counter(step);(空格连接,浏览器自动合并) -
content: "Step" counter(step) ".";(多段用空格分隔)
Less里如果想动态拼前缀,得用字符串插值+转义:
.step-counter(@prefix: "Step") {
counter-reset: step;
> li {
counter-increment: step;
&::before {
content: ~"@{prefix} " counter(step) ".";
margin-right: 0.5em;
font-weight: bold;
}
}
}
兼容性差的counter-style需要备选方案
counter-style自定义(比如用图片、emoji做序号)只在较新Chrome/Firefox支持,Safari至今不支持@counter-style规则。别指望用Less编译出跨浏览器一致的花式序号。
真要兼容旧浏览器,老实用background-image或伪元素content硬编码序号字符(如content: "①";),再配合list-style: none关掉原生序号。
Less能帮上忙的,只是批量生成这些硬编码规则:
.fallback-nums(@list: ① ② ③ ④ ⑤) {
> li {
list-style: none;
position: relative;
padding-left: 2em;
&::before {
position: absolute;
left: 0;
content: extract(@list, @index);
}
}
}
但注意extract()只能用于静态列表,无法动态对应
:nth-child(n)反而更稳。
真正难的从来不是怎么写出来,而是判断该不该用counter:当序号要响应JS插入/删除、要嵌套多层、要和DOM结构强绑定时,才值得折腾;否则,纯视觉序号用background或content字面量更省心。


















