less 的 .namespace 语法不解决 css 命名冲突,仅是嵌套糖语法,编译后仍为全局规则;真正有效的是唯一根类+bem 风格、带前缀的变量命名、统一变量收口及运行时补类等人工约束实践。

Less 的 .namespace 或 #namespace 语法不能解决 CSS 命名冲突——它不生成作用域,只是选择器嵌套的写法糖,编译后仍是全局 CSS 规则。
为什么用 .ui-modal { .title { ... } } 还是会冲突
编译结果是 .ui-modal .title,看起来有前缀,但只要页面里另一个组件也用了 .title 类(比如 <div class="title"> 在非 <code>.ui-modal 下),它的样式就可能被意外覆盖或反向覆盖。根本原因:CSS 本身没有运行时作用域,Less 也不加哈希、不插 scoped 属性、不限制 HTML 中 class 的实际使用方式。
-
.title在不同命名空间里重复定义,编译后还是同名类,浏览器按优先级和顺序渲染,不认“谁写的” - HTML 没强制要求把
.title套在.ui-modal里,前端 runtime 完全不管 Less 结构 - 嵌套层级越深(如
.ui-modal .header .title span),选择器权重越高,反而更容易压垮第三方 UI 的样式
真正能落地的命名空间实践:唯一根类 + BEM 风格
不是靠 Less 语法自动隔离,而是靠人工约定+结构约束。核心是让顶层类名具备高唯一性,并用 &__xxx 显式绑定子元素。
- 顶层类名必须和 JS 组件名对齐,例如
.user-profile-card,避免用泛义名如.card - 所有内部样式都从该根类出发嵌套:
.user-profile-card { &__avatar { width: 40px; } &__name { font-weight: bold; } } - 禁止在命名空间内写标签选择器:
.user-profile-card { button { ... } }会污染全局所有button - HTML 必须显式添加根类:
<div class="user-profile-card">...</div>,否则样式不生效
@import 顺序和变量冲突比选择器更隐蔽
Less 所有文件扁平合并作用域,@primary-color 在 buttons.less 里重定义一次,整个项目后续所有用到它的地方都会变——而且不报错、不提示、开发者工具里查不到源头。
- 变量必须带模块前缀:
@btn-primary-bg、@form-input-padding,禁用裸名@color、@size - 所有公共变量统一收口到
variables.less,其他文件只@import,不重定义 -
@import (reference)不阻止变量注入,它只跳过 CSS 输出,变量照样进全局作用域 - 构建时可用
lessc --lint检查重复变量定义(Less 4.0+)
当第三方 CSS 已经没前缀,怎么兜底
你加了 .my-kit 前缀,但埋点 SDK 或广告脚本注入的 .modal 样式没前缀,照样能干掉你的规则。
- 提升权重不是长久之计:
.my-kit .button.button(重复类名)或.my-kit > .button可临时压制,但会让选择器越来越难维护 - 关键基础样式(如
box-sizing、font-family)直接写在:root或html上,不依赖前缀 - 动态插入的第三方浮层,如果无法控制其 class,只能用 JS 在插入后手动补
.my-kit类,或用!important(仅限极少数不可妥协场景)
最易被忽略的一点:命名空间对变量、mixin、函数完全无效。把 @color 塞进 .ui-button { ... } 块里,它既不会局部生效,也不会防止被覆盖——变量作用域只取决于 @import 顺序和声明位置,和嵌套结构无关。











