应使用--active而非is-active控制视觉样式,因--active是BEM原生修饰符,语义明确、可静态存在、CSS独立生效且不依赖JS;is-active仅为社区状态类,易被误删、需与块名共存、仅作JS/A11y信号辅助。

直接结论:别用 is-active 单独控制样式,它不是BEM修饰符,不能替代 --active;真要共存,is-active 只能当 JS 信号或 A11y 辅助,视觉必须靠 --active。
为什么 is-active 不能单独写 CSS 规则
浏览器不识别语义,只认类名字符串。如果只定义 .is-active { color: red; },那所有带 is-active 的元素——.tooltip.is-active、.sidebar.is-active、.modal.is-active——都会被染红。这不是状态隔离,是样式泄漏。
- 构建工具(如 PurgeCSS)扫描不到孤立的
.is-active,极易误删 - DevTools 里看不出这个
is-active属于哪个组件,调试成本翻倍 - 屏幕阅读器完全忽略
is-active,必须额外加aria-current="page"或aria-selected="true"
--active 才是 BEM 正规军,必须绑定块/元素使用
--active 是 BEM 原生修饰符,表示“这个实例在设计上就是活跃态”,比如 SSR 渲染时已知当前 tab。它必须和块或元素名紧耦合:.nav__item--active、.tab__panel--active,不能脱钩。
- CSS 规则得写成
.nav__item--active { font-weight: 600; },删掉 JS 页面照样显示正确 - PurgeCSS 能从 HTML 中静态识别
nav__item--active,不会误删 - 动画、伪类、过渡效果都得显式写在
--active规则里,例如.btn--loading { transition: opacity .2s; }
JS 切换时怎么安全操作多个状态类
别拼字符串,用 classList.toggle 显式控制每个修饰符。多个状态共存(如 --disabled 和 --loading)时,CSS 必须单独覆盖组合场景,不能指望层叠“自动生效”。
立即学习“前端免费学习笔记(深入)”;
- 正确写法:
el.classList.toggle('btn--disabled', isDisabled); el.classList.toggle('btn--loading', isLoading); - 组合样式必须显式声明:
.btn--disabled.btn--loading { opacity: 0.5; cursor: not-allowed; } - 禁止嵌套修饰符:
btn--disabled--loading是非法语法,IDE 不识别,PostCSS 插件会跳过
容易被忽略的兼容性细节
最常漏的是 SSR 与 CSR 状态对齐。服务端渲染出 .tab__item--active,客户端 JS 初始化时若没同步清除/添加对应类,就会触发 FOUC 或状态错乱。
- React/Vue 中,确保初始
className由服务端传入 props 决定,而非仅靠 useEffect 派发 - 禁用态除了加
--disabled,还得同步设原生disabled属性,否则键盘用户仍可聚焦按钮 - 动画类必须用
--开头,is-fading这类命名会被 Stylelint 当作普通类,无法参与 BEM 工具链校验


















