Less中&伪类组合必须紧贴书写无空格,否则会错误解析为后代选择器或生成冗余规则;&不穿透嵌套层级、不支持变量插值、不响应运行时类名,需严格按编译期字面逻辑使用。

直接用 & 写伪类或状态组合,绝大多数时候能编译出你想要的选择器,但只要中间多一个空格、少一个冒号,或者嵌套层级理解错,结果就完全跑偏——不是没生效,而是匹配到了别的元素上。
伪类组合必须紧贴 & 写,不能有空格
这是最常导致样式“不生效”的原因。Less 把带空格的 & :hover 当作后代选择器,而不是自身状态。
-
&:hover→ 编译为.btn:hover(正确) -
& :hover→ 编译为.btn :hover(错误,匹配 .btn 内任意悬停元素) -
&:focus:valid→ 编译为.input:focus:valid(单个选择器,同时满足两个状态) -
&:focus &:valid→ 编译为两条独立规则:.input:focus和.input:valid(不是组合) - 复合伪类如
&:not(:first-child)必须一气呵成,拆开写(比如&:not+:first-child)会报错或语义错乱
伪元素 ::before/::after 同样不能加空格
空格会让 & 失去绑定目标,从“自身伪元素”降级为“子元素伪元素”。
-
&::after→.icon::after(正确) -
& ::after→.icon ::after(错误,匹配 .icon 内部所有 ::after) -
&:hover::before是合法的,表示“悬停时渲染自身 before”,但&:hover &::before就是.card:hover .card::before,中间多了空格和重复类名,几乎总是错的 - 旧写法
&:before虽然部分 Less 版本能编译,但浏览器只认双冒号语法,实际无效
多层嵌套时 & 只认字面最近父级,不穿透
很多人以为三层嵌套里写一个 & 就能带上最外层类名,其实它只展开到直接上一级选择器。
-
.modal { .header { &::before { } } }→ 编译为.modal .header::before(注意空格,是后代关系) - 如果想让
::before属于.modal本身,就得显式写.modal::before或把规则提到外层 -
.container { .sidebar { &__title { } } }→.container .sidebar__title,不是.container__title;&不跨层,“穿透”需要手动重复,比如.container--active .sidebar { .container--active & { } } - 超过 3 层嵌套后,
&展开的选择器容易冗长、语义混乱,建议拆成独立类名,别硬靠&拼
BEM 风格修饰符拼接要小心顺序和层级
& 拼接 BEM 是方便,但修饰符(--modifier)和元素(__element)的位置一错,生成的类名就违背语义。
-
.btn { &__icon { } &--primary { } }→.btn__icon和.btn--primary(符合 BEM) - 想写
.btn__icon--large,得用&__icon { &--large { } },不能写成&__icon--large—— 后者虽然语法通过,但逻辑上--large应该修饰__icon,而这种写法没问题;真正错的是想表达.btn--large__icon却硬套&__icon,那只能手动写或换结构 - 变量无法参与
&拼接,@{block} { &__text { } }中的&不会插值,得用.@{block}__text显式拼 - 动态加的类(如 JS 插入的
.theme-dark)不会被&捕获,它只在编译期展开字面父选择器,运行时状态对它完全透明
真正麻烦的不是语法记不住,而是 & 看似智能,实则完全静态——它不感知 HTML 结构变化、不响应 JS 动态类、也不理解 BEM 意图,只机械拼接。写完务必看编译输出,别信“应该没错”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











