响应式开发必须统一使用 min-width 媒体查询并收口断点至变量,BEM 修饰符应表达语义化状态而非设备,媒体查询需包裹修饰符声明且 JS 应用 matchMedia 监听而非 resize。
混用 max-width 和 min-width 是响应式样式冲突的头号来源。比如同时存在 @media (max-width: 768px) 和 @media (min-width: 768px),在精确 768px 宽度下两者都匹配,最终生效的是源码顺序靠后的规则——这不是设计,是不可控的巧合。
所有断点必须统一用 min-width,并定义为 Sass/Less 变量(如 $bp-md: 768px),禁止在 CSS 中硬写像素值或在类名里嵌入数字。
@media (min-width: $bp-md) 要放在整个组件样式文件的末尾,包裹所有修饰符相关声明card__content--stacked,不出现 --md、@lg 等断点标识_breakpoints.scss,JS 里读取断点也应从此处导入,而非重复定义写 nav__list--mobile 或 card--desktop 是错的。这类名字把渲染环境(mobile/desktop)当成了状态,但 BEM 修饰符该描述的是「布局意图」或「视觉变体」,比如 nav__list--vertical、card--compact、card__content--stacked。
这些修饰符本身不生效,它们只是钩子;真正控制显示逻辑的,是外部 @media 块里对它们的引用。
nav__list--vertical 在 @media (max-width: 767px) 内才设 flex-direction: column
card--compact 可以在桌面端控制 gap: 0.5rem,在移动端媒体查询中覆盖为 gap: 0.25rem,无需新增修饰符card--stacked@md 或 button--primary-sm 这类混合命名,浏览器根本不识别 @ 或 -sm 的语义用 window.addEventListener('resize', ...) 判断屏幕宽度再加类,性能差、易漏触发、且 SSR 场景下首屏渲染和 JS 执行不同步,导致 FOUC 或 layout shift。
正确方式是用 window.matchMedia() 创建媒体查询监听器,它能精准反映当前断点是否匹配,并天然支持服务端不执行(无副作用)。
const media = window.matchMedia('(max-width: 767px)'); media.addEventListener('change', e => el.classList.toggle('nav__list--vertical', e.matches));
useEffect + matchMedia 封装 Hook,避免每次 render 都新建监听器className={`nav__list ${isMobile ? 'nav__list--vertical' : ''}`} ❌ —— 应交由媒体查询控制,JS 只负责初始状态同步导航从横向变成纵向后,.nav__item--active 样式失效,往往不是 JS 没加类,而是 CSS 规则没随布局变化升级选择器权重。
当父容器应用了 --vertical 修饰符,所有依赖该布局的子元素样式都需显式限定作用域,否则会被通用规则覆盖或因层级变化而失配。
.nav__item--active { background: #007bff; } —— 它在 .nav__list--vertical 下可能被忽略.nav__list--vertical .nav__item--active { background: #007bff; padding: 1rem 0; }
nav__item--active 能搜到全部,但 grep .nav__list--vertical .nav__item--active 才能确认覆盖完整HelloKittyMyDreamStore新手开局攻略HelloKittyMyDreamStore零基础入门玩法指南
暗黑不朽秘境暗黑不朽秘境手游高效刷级与快速升级实战指南
超维进化手游荒野游侠怎么玩|荒野游侠角色培养、副本攻略与实战技巧详细说明
铸兵之王最强装备排行榜一览铸兵之王全流派毕业装备推荐
小米路由4a千兆版500兆怎么设置(小米路由4a千兆版500兆设置方法)
宗师之上心法选择攻略宗师之上最强心法搭配与进阶实用技巧