:focus嵌套失效因Less中&:focus脱离元素上下文会编译为:focus被浏览器忽略;必须挂载在具体选择器如input{&:focus{}}内。

为什么 :focus 嵌套在 input 里会失效?
Less 编译时按 CSS 规则顺序展开嵌套,input:focus 写成 input { &:focus { ... } } 是对的,但写成 &:focus { ... } 在顶层或父选择器外就会编译成 :focus(无元素名),浏览器直接忽略。
- 必须确保
&:focus的上层有具体元素选择器,比如input { &:focus { border-color: #007bff; } } - 别在变量定义块或 mixin 外直接写
&:hover这类伪类——它没挂载点,Less 不知道该“&”指谁 - 如果用
.form-control { input { &:focus { ... } } },最终是.form-control input:focus,层级加深,可能被已有样式覆盖
怎么用一个 mixin 统一控制 input、textarea、select 的禁用态?
不同表单控件的禁用表现不一致:input[disabled] 灰掉文字但保留边框,select[disabled] 可能连下拉箭头都变灰,而原生 textarea 没有统一禁用视觉反馈。靠重复写三遍 [disabled] 容易漏改。
- 写个接收标签名参数的 mixin:
.form-disabled(@tag) { @{tag}[disabled] { background-color: #f8f9fa; color: #6c757d; cursor: not-allowed; } } - 调用时明确传入:
.form-disabled(input); .form-disabled(textarea); .form-disabled(select); - 注意:IE11 不支持
select[disabled]的部分样式(如color),得加select:disabled单独处理,否则灰度不一致
:valid 和 :invalid 在 Less 里怎么避免样式污染?
HTML5 表单验证伪类默认在用户未输入时就触发 :invalid(比如必填字段为空),导致页面一加载就显示红边框,体验突兀。Less 本身不干预触发时机,但能帮你约束作用范围。
- 别全局写
input:invalid { border-color: red; }——它会作用到所有input,包括隐藏域和搜索框 - 限定在带校验逻辑的容器内:
.form-group--validated input:invalid { border-color: #dc3545; } - 配合
:user-invalid(Chrome 102+ / Firefox 103+)更精准:input:user-invalid { ... },但得加注释说明兼容性断层 - 服务端渲染时若已知字段有效,可加
data-valid="true",用属性选择器替代伪类,避开浏览器初始状态问题
为什么嵌套太多层后编译出的 CSS 选择器特别长?
Less 嵌套是语法糖,每层 & 都会拼接父选择器。比如 .form { .field { input { &:focus { ... } } } } 编译成 .form .field input:focus,看着还行;但加个 body.theme-dark 外层,就变成 body.theme-dark .form .field input:focus,权重飙升,后续想用简单选择器覆盖几乎不可能。
立即学习“前端免费学习笔记(深入)”;
- 超过 3 层嵌套就该警觉——不是不能写,而是要问:这个样式是否真依赖全部父级?
- 用
&_modifier替代深层嵌套,比如把.form .field input:focus提前定义为.form-field-input:focus - 必要时用
!important是信号:嵌套结构已经失控,该重构了
表单样式真正难的不是写出来,是让 :focus-within、:-webkit-autofill 这些边缘状态在嵌套结构里还能被单独调整,又不破坏现有权重体系。多一层嵌套,调试成本翻倍。


















