next.js 14 中纯 css 文件不支持 bem,必须使用 css modules(如 button.module.css)实现作用域隔离与 ssr 安全;bem 块需严格对应小写中划线目录、首字母大写组件名及同名 module.css 文件,类名须以块名开头且扁平化书写。

Next.js 14 中直接在 styles/ 下写纯 CSS 文件(如 button.css)并指望它自动支持 BEM 是行不通的——CSS Modules 才是官方推荐且 SSR 安全的路径,而纯 CSS 文件没有作用域隔离,类名会全局污染。
为什么不能把 BEM 类名直接写在全局 CSS 里
Next.js 的 globals.css 或任意 .css 文件会被当作全局样式注入。一旦你写 .button__icon,它就可能被其他组件意外覆盖或影响,尤其在多人协作时:.card__button 和 .button__icon 看似无关,但若都用了 display: flex + gap,权重冲突就藏不住。更关键的是,服务端渲染时无法保证 class 名生成顺序一致,容易触发 hydration mismatch。
必须用 CSS Modules 文件对应每个 BEM 块
每个 BEM 块(如 button)必须有独立的 Button.module.css 文件,且文件名首字母大写(与 React 组件名对齐),路径建议为 components/Button/Button.module.css。这不是约定俗成,而是为了确保:
-
import styles from './Button.module.css'能稳定映射到源码中写的.Button、.Button__icon、.Button--primary - Webpack 构建时哈希只作用于底层实现,JSX 中仍可读、可推导
- 避免在
components/shared.module.css这类聚合文件里混写多个块——这等于主动放弃 BEM 的块级作用域
如何在 CSS Modules 文件里写符合 BEM 的类名
在 Button.module.css 中,直接按 BEM 规范书写,不加前缀、不嵌套、不拼接:
详细的 Three.js 3D 图形参考,涵盖场景设置、相机、几何体、材质、光照、动画、控制器、加载器、数学工具和调试。
.Button {
padding: 0.5em 1em;
}
.Button__icon {
margin-right: 0.25em;
}
.Button--primary {
background-color: #007bff;
}
.Button--disabled {
opacity: 0.6;
cursor: not-allowed;
}
注意以下三点:
- 所有类名必须以块名开头(
.Button),禁止出现.icon或.btn这类泛义名 - 修饰符(
--primary)和元素(__icon)必须用方括号语法访问:styles['Button--primary'],因为连字符在 JS 中非法 - 不要写
.Button .Button__icon—— CSS Modules 不支持真嵌套,且违背 BEM “扁平化”原则
目录结构必须与块名严格一致
Next.js 14 的 App Router 下,BEM 块目录必须小写+中划线,且与类名完全匹配:
- 正确:
components/user-profile/UserProfile.module.css→ 类名.user-profile - 错误:
components/UserProfile/(大小写敏感,CI 可能 fail)或components/profile/(grep 查不到user-profile__avatar) - 禁止三层嵌套:
components/button/icon/是错的;.button__icon就该定义在Button.module.css内部,不是独立块
BEM 的边界感很实在:一个块就是一个目录、一个 CSS Modules 文件、一个 React 组件文件。少一个,就容易在修改按钮禁用态时,不小心动到卡片的悬停逻辑。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










