mixin封装交互状态需接收选择器参数,如.interactive-states('.btn'),禁用&:hover写法;disabled需同时匹配[disabled]和[aria-disabled="true"];避免循环调用以防css体积膨胀。

Less里怎么用Mixin封装:hover/:focus这类交互状态
直接把伪类写进Mixin里是最常用也最稳妥的做法,不是所有状态都适合抽离,但:hover、:active、:focus、:disabled这四个高频组合完全可以。
关键在于Mixin要接收选择器上下文,否则编译后样式会丢失层级关系。别用.button:hover这种硬编码,得让调用方决定作用对象。
- 写法必须带参数:
.interactive-states(@selector) { @selector:hover { ... } } - 调用时传入选择器片段,比如
.interactive-states('.btn');,而不是.interactive-states(btn);(后者会被当成变量) - 如果需要支持多状态叠加(如
:hover:focus),得单独再写一个Mixin,不要强行塞进同一个里——语义混乱,维护成本高
为什么不能直接在Mixin里写&:hover
因为&在Mixin内部指向的是Mixin自身定义的作用域,不是调用它的地方。你写&:hover,编译出来就是.mixin-name:hover,完全没用。
真正有效的写法是把&留在调用侧,让Mixin只负责声明块内容:
.interactive-states() {
&:hover { color: #007bff; }
&:active { transform: translateY(1px); }
}
.btn {
.interactive-states();
}
这样编译结果才是.btn:hover和.btn:active。漏掉这层理解,90%的封装都会失效。
disabled状态怎么兼容原生表单控件和自定义组件
原生<button disabled></button>和<input disabled>走的是HTML属性逻辑,而自定义组件(比如.custom-btn[aria-disabled="true"])得靠属性选择器。Mixin得同时覆盖两种写法,否则样式不生效。
- 统一用
[disabled]匹配原生控件 - 加一层
[aria-disabled="true"]适配React/Vue组件库 - 避免只写
:disabled——它对div或自定义标签无效 - 示例:
&[disabled], &[aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; }
性能和编译体积容易被忽略的点
每次调用Mixin都会复制一遍CSS规则,如果在循环中用(比如遍历按钮类型),生成的CSS可能翻倍。不是语法错误,但上线后查Network会发现样式表比预期大一截。
- 优先用CSS类名控制状态(
.is-disabled),而不是纯伪类+Mixin - 如果必须用伪类,确保Mixin只在顶层组件类下调用一次,别在嵌套选择器里反复调用
- Less 4.0+支持
extend,但:hover类不能被extend,这点文档没明说,实测会静默失败
状态封装真正的难点不在写法,而在厘清「谁触发状态」「谁响应状态」「状态是否可预测」——CSS本身没状态管理能力,全靠约定和约束撑住。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











