直接写 .btn 或 .header 必然导致样式冲突,因 CSS 是全局作用域,同一类名在不同模块中可能被定义为不同样式,生效取决于加载顺序或权重;且 .header .logo 等结构依赖型选择器易因 DOM 变动失效。

为什么直接写 .btn 或 .header 必然导致样式冲突
因为 CSS 是全局作用域,.btn 在登录页、弹窗、侧边栏里可能被不同人定义成不同高度、颜色、甚至 display 类型。谁的样式生效,取决于加载顺序或选择器权重,而不是“这个按钮属于哪个功能”。更危险的是,.header .logo 这种依赖 DOM 结构的选择器,一旦页面加了个 wrapper div,样式就断——它不是写错了,是根本没设计隔离边界。
如何用 stylelint-selector-bem-pattern 卡死命名出口
光靠文档和 Code Review 拦不住手滑。必须让违规类名在保存时就报错:
- 安装插件:
npm install --save-dev stylelint-selector-bem-pattern - 在
.stylelintrc.js中配置:module.exports = { plugins: ['stylelint-selector-bem-pattern'], rules: { 'plugin/selector-bem-pattern': { componentName: '[a-z][a-zA-Z0-9]+', styleType: 'bem' } } }; - 它会立刻拦截:
.header .logo、.btn-primary、CardTitle(大驼峰)、_input(下划线开头)
block__element--modifier 三段怎么拆才不翻车
不是套公式,而是每一段都绑定具体语义责任:
-
block必须是独立可复用的业务单元,如search-form、user-card;禁用left-nav、big-btn这类带位置/样式词的命名 -
element用双下划线连接,且只能直属 block,user-card__avatar合法,user-card__avatar__icon违规——后者该提成新 block:avatar-icon -
modifier用双短横,只表达外观或行为变体,button--disabled合理,button--loading要小心:如果 loading 状态需 JS 控制 class 切换,没问题;但如果它还触发了网络请求逻辑,说明已越界,该抽到 JS 层
老项目怎么落地,又不让开发卡住
全量重命名等于停工一周。真正可行的是守住新增入口、逐步收编旧边界:
立即学习“前端免费学习笔记(深入)”;
- 新组件(如弹窗、筛选栏)100% BEM,目录即 block 名:
modal/下只允许出现modal、modal__header、modal--fullscreen - 对高频冲突类(如全局
.table),先用 wrapper 包一层:<div class="data-table">…</div>,后续扩展全走data-table__row - VS Code 安装
BEM Tools插件,输入search-form按 Tab,自动补全search-form__input和search-form--compact,减少手误成本
最常被忽略的点:BEM 不是让类名变长,而是让每个类名自带可搜索锚点。grep -r "card__title" 能瞬间定位全部标题样式,而不用在 12 个文件里猜哪个 .title 是卡片用的。


















