不能在css reset中协调bem命名的全局基准,因reset目标是抹平浏览器差异,bem目标是隔离组件作用域;全局通配符如* { box-sizing: border-box; }会无差别穿透dom,破坏第三方组件布局及继承链,正确做法是将reset限定于bem block根节点并用scss mixin封装。

不能在 CSS Reset 中协调 BEM 命名的全局基准——Reset 和 BEM 本就不该共用“全局”这个概念。Reset 的目标是抹平浏览器差异,BEM 的目标是隔离组件作用域;把两者强行塞进同一套“全局基准”,只会让 reset 破坏 BEM 封装,或让 BEM 被 reset 劫持。
为什么 * { box-sizing: border-box; } 会破坏 BEM 组件
这条规则看似无害,实则无差别穿透所有 DOM 层级:一旦你在 .user-card 里嵌入第三方 el-date-picker,它的内部 .el-input__inner 就会被强制改写盒模型,而你根本无法控制该组件是否依赖 content-box 布局。更严重的是,它还会污染 iframe、web-component 或任何动态插入的 legacy 片段。
-
* { margin: 0; padding: 0; }会让.user-card__title和.el-select .el-selection同时失去默认间距,但前者你可控,后者你不能动 - Reset 若写在
html或body上(如html { font-size: 16px; }),会劫持整个继承链,导致.card__title在不同上下文里字号不一致 - BEM 不靠父级样式传递,但全局 reset 强行注入基础属性,等于替换了 BEM 的“语义起点”
正确的 Reset 作用域必须限定在 BEM block 根节点
Reset 规则只应出现在明确属于你项目的 BEM block 容器上,例如 .form-item、.search-form、.user-card,且仅影响其直系后代和伪元素。
- 推荐 SCSS mixin 封装:
@mixin reset-block { & *, & *::before, & *::after { box-sizing: border-box; } },然后在每个 block 中调用 - 表单控件重置必须限定范围:
.form-item button、.form-item input,而非全局button或input - 避免使用后代选择器如
.form-item div input,改用.form-item > * input或直接作用于 wrapper 元素 - 对第三方组件的干预,必须显式声明:
.form-item [class*="el-input"]或 Vue 的:deep(.el-input__inner)
哪些 Reset 行为必须从 BEM block 中剥离
Reset 层只负责“技术性归零”,不承担语义职责。以下内容不应出现在 block 级 reset 中,而应移入独立的 _base.scss 或 typography 模块:
-
html { font-size: 16px; }—— 字号基准属于排版系统,不是 reset 职责 -
body { line-height: 1.5; }—— 行高影响所有文本继承,与 block 无关 -
h1, h2, p { margin-top: 0; }—— 这类语义标签重置应统一收口,不随 block 变化 -
button { appearance: none; }—— 外观重置若未限定 block,会覆盖所有按钮(含第三方)
真正容易被忽略的点在于:BEM 的封装性不是靠 class 名长度维持的,而是靠 reset 是否“守界”。一旦你在 _reset.scss 里写了通配符,就等于主动交出了组件边界的控制权——后续所有“为什么这个第三方组件突然变样了”的问题,根源都在这一行 * 里。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











