初级项目css应先分三层:_base.css(重置、变量、工具类)、_layout.css(容器/页眉页脚等大结构)、_components.css(按ui单元区块注释分隔);命名用简化bem,禁用嵌套选择器。

直接上手就能用,不需要等设计系统或工具链就绪——初级项目用模块化CSS,核心是“先分层、再命名、不嵌套”。
怎么划分 CSS 文件层级才不乱
别一上来就建 components.css 或 utils.css。先按职责切三类文件,每类一个物理文件:
-
_base.css:只放重置(*, body, h1–h6, a)、字体、颜色变量(--color-primary)、通用工具类(.u-hidden,.u-mt-2) -
_layout.css:只管大块结构,比如.container,.header,.footer,.grid—— 不出现任何组件细节样式 -
_components.css:每个独立 UI 单元一个区块,用注释隔开,例如:/* ====== Button ====== */.btn { … }.btn--primary { … }
没用到 PostCSS 或构建工具?没关系,这三个文件用 @import 在主样式表里顺序引入就行,浏览器兼容性无压力。
BEM 命名在初级项目里怎么简化落地
不用死守“必须双下划线”,但要守住两个底线:不依赖 DOM 层级、不写 .card .title 这类路径式选择器。实际操作中:
- 块名用小写+短横线:
.search-form,.user-card(不是SearchForm或userCard) - 元素用双下划线:
.search-form__input,.user-card__avatar—— 这个不能省,它是解耦关键 - 修饰符用双短横线:
.search-form--compact,.user-card--loading;禁用单独使用的修饰符,比如.--error这种无效写法 - 遇到“按钮里的图标”这种场景,别写
.btn__icon然后又加个.icon--small,直接写.btn__icon和.btn--small .btn__icon—— 修饰符作用于块,样式继承自然发生
为什么初级项目更要避免选择器嵌套
新手常以为 SCSS 的 &__text 是为了“写得快”,其实它埋的雷比你改 HTML 结构还早:
- HTML 加一层
<div class="wrapper">,<code>.card__title样式照常生效;但.card .title就断了,你得同步改 CSS - 审查元素时,看到
.card__title就知道它属于 card 模块,而.title可能来自 anywhere —— 调试成本翻倍 - 团队协作中,别人加了个
.sidebar .title,你的.card .title突然被覆盖,因为特异性相同、后声明者胜出 - 所有现代构建工具(Vite/Webpack)对 BEM 类名做 CSS Modules 或 scope 处理时,都依赖扁平类名结构;嵌套选择器会绕过作用域隔离
- 一个 CSS 区块里同时出现
.form和.validation-message,且后者在登录页、注册页、编辑页都用 —— 提出来成_validation.css -
.product-list里写了.product-list__item和一整套.rating-star样式 —— 星级组件明显可复用于用户评论、店铺评分,单独抽离 - 某个模块的 CSS 行数超过 80 行,且内部有 3 个以上状态(
--loading,--error,--success)和 2 种布局变体(--grid,--list)—— 它已经不是“模块”,是“子系统”了
什么时候该把一个模块拆成两个文件
不是按“组件数量”拆,而是看“是否能独立复用”。以下信号出现任一,就该拆:
拆文件不是为形式主义,是让每次 git blame 或 PR review 时,你能一眼定位到“这个改动只影响登录表单,不影响整个表单体系”。真正容易被忽略的,是初期舍不得拆——等 _components.css 长到 2000 行,再拆,代价是重构、测试、沟通,远超一开始多建一个文件的成本。











