修饰符名中禁止使用@md或--mobile等断点标识,因其不被浏览器解析且引发维护、协作与工具链问题;断点必须统一收口至_breakpoints.scss并集中定义变量,媒体查询须统一用min-width或max-width,修饰符命名采用“动词+范围”结构如nav-menu--hidden-below-md,React中应通过useMediaQuery等CSS层逻辑控制类名,禁用字符串拼接。

修饰符名里不能出现 @md 或 --mobile
浏览器根本不解析类名里的 @md、--mobile 这类字符串,它们只是普通文本,不会触发任何媒体查询行为。写 card--stacked@sm 等价于写 card--stacked-abc,CSS 引擎照单全收,但完全无效。
这类写法还会导致三个实际问题:
- 断点值改了(比如从
768px改成744px),你得同步改 HTML 类名、JS 切换逻辑、CSS 文件里的@media块——漏一处就出 bug - 不同人对
sm理解不一致:有人指640px,有人按768px,协作时样式互相覆盖却查不出原因 - PurgeCSS 等工具识别不到真实生效的类,可能误删
card--stacked@sm,因为它的选择器从未在 CSS 中显式声明过
@media 必须统一收口到 _breakpoints.scss
所有断点数值必须集中定义,例如:
$bp-md: 768px;<br>$bp-lg: 1024px;
然后在 _breakpoints.scss 末尾统一包裹对应规则,确保修改变量后,所有依赖自动适配:
@media (max-width: $bp-md - 1) {<br> .nav-menu--hidden-below-md { display: none; }<br>}<br>@media (min-width: $bp-lg) {<br> .card--stacked-above-lg { flex-direction: column; }<br>}
关键点:
- 禁止在组件 SCSS 文件里直接写
@media—— 断点逻辑一旦散落各处,后期根本没法全局调控 - 媒体查询必须统一用
min-width或统一用max-width;混用会导致边界值(如768px)同时命中两个规则,最终生效的是源码顺序靠后的那条,不可预测 - Stylelint 可校验每个
--below-md是否有配套的@media (max-width: $bp-md - 1)
修饰符命名要用动词 + 范围结构,比如 nav-menu--hidden-below-md
修饰符只表达「状态意图」,不暴露「生效条件」。它回答的是“我要什么”,而不是“在什么屏幕下才这样”。
推荐结构:[动词]-[范围],例如:
-
nav-menu--hidden-below-md(明确是“隐藏”,且“低于 md 断点”) -
card--stacked-above-lg(明确是“堆叠”,且“高于 lg 断点”)
避免这些命名:
-
card--mobile:语义不清,“mobile” 是指仅显示?还是隐藏?还是布局变化? -
block--sm-hidden:“sm” 指尺寸?断点?哪个断点值?没人能一眼确认 -
button--primary@lg:直接违反 BEM 原则,修饰符不该承担条件判断职责
React 中用状态控制类名,别拼接字符串
JS 层不该监听 resize,也不该动态拼接断点类名。正确做法是把断点判断逻辑抽到 CSS 层,HTML/JS 只保留语义化修饰符。
示例(React + CSS Modules):
const isMobileView = useMediaQuery('(max-width: 767px)');<br>className={clsx('card', isMobileView && 'card--stacked')}
必须禁用的写法:
-
className={`card card--${size}@${breakpoint}`}❌ -
className="card card--mobile"❌ -
className={styles['card__title']}(绕过 Block 封装)❌
ESLint 必须启用自定义规则拦截非语义类名拼接,否则团队协作几天就会失控。
最容易被忽略的细节:服务端渲染(SSR)无法获取视口宽度,JS 动态加类会导致 FOUC 或 layout shift;而用 useMediaQuery 或原生 window.matchMedia 首次加载即检查,可规避这个问题。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











