css无继承概念,.button--primary需与.button共存于class才能生效;修饰符应只覆盖特定属性,避免重复定义或全局劫持。

为什么 .button--primary 单独写不继承 .button 的样式
因为浏览器根本不认 .button--primary 是 .button 的“子类”——CSS 没有继承概念,只有层叠(cascade)和选择器匹配。修饰符类名本身是独立的,它不会自动带上基础块的任何声明。
常见错误现象:.button { padding: 8px 16px; } 写了,.button--primary { background: blue; } 也写了,但最终按钮没 padding。原因就是 HTML 里只写了 class="button--primary",漏掉了 button 这个基础类。
- 必须在 HTML 中显式共存:
class="button button--primary"✔️ - CSS 中推荐用单类选择器,但语义上仍需依赖共存:
.button--primary { background: blue; }(前提是 DOM 有.button) - 不要写成
.button .button--primary—— 这不仅权重虚高,还让样式依赖 DOM 结构,JS 动态移除父级就失效
.button--primary 和 .button--large 同时存在时,padding 被覆盖怎么办
这不是 BEM 不支持叠加,而是两个修饰符都改了同一属性(比如都设了 padding),后声明的规则直接覆盖前一个。浏览器不管语义正交,只看层叠顺序和权重。
- 避免不同修饰符重复定义同一属性:让
.button--primary只管颜色、边框色;.button--large只管尺寸、内边距 - 如果必须叠加控制(如大号主按钮),优先用组合选择器显式覆盖:
.button--primary.button--large { padding: 12px 24px; } - 构建工具如
cssnano的mergeLonghand可能误删重复类名,导致.button--primary.button--large被压缩成单个类,务必在配置中禁用该优化
如何让 .button--disabled 保留 .button 的字体大小,只改 opacity 和 cursor
关键不是“继承”,而是“不破坏”。BEM 的设计哲学是每个类名具备完整渲染能力,所以 .button--disabled 应该只覆盖它关心的状态属性,其余保持原样。
-
.button--disabled里只写:opacity: 0.5;、cursor: not-allowed;、pointer-events: none; - 绝对不要在
.button--disabled里重写font-size、padding、background等非状态相关属性 - 如果发现字体变小了,大概率是某个全局规则如
.disabled * { font-size: 12px; }在劫持,得用 DevTools 的 “Computed” 面板定位并干掉这类泛化选择器
第三方组件里加 BEM 修饰符为什么没效果
比如给 Ant Design 的 ant-btn 加了 my-button--secondary,但样式不生效——问题往往不在命名,而在作用域和加载顺序。
- 确保你写的 CSS 文件比第三方样式后加载,否则会被压住;或者用更明确的作用域限定,如
.my-button.ant-btn.my-button--secondary - PurgeCSS / UnoCSS 等工具可能把动态添加的修饰符(如
my-button--loading)识别为未使用而删除,safelist必须包含正则:/my-button--(secondary|loading|disabled)/ - 最稳妥的方式是封装一层 DOM:
<div class="my-button ant-btn"><slot></slot></div>,然后所有修饰符都作用于.my-button,不碰.ant-btn内部结构
真正容易被忽略的是:BEM 修饰符的“覆盖”不是靠权重赢,而是靠精准控制哪些属性该变、哪些该留。一旦开始在修饰符里补全所有样式(比如把 padding、font-size 全抄一遍),就等于放弃了 BEM 的解耦前提。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











