动画类名必须是--modifier,如.modal--fade-in,不能独立为.fade-in;须绑定具体组件、显式声明animation/transition、禁止嵌套修饰符、平级组合状态、js控制需匹配事件时机。

动画类名必须是 --modifier,不能独立存在,也不能脱离块上下文;否则 CSS 不生效、JS 控制失锚、工具链识别失败。
为什么 --fade-in 必须绑定到具体 Block,比如 .modal--fade-in
直接写 .fade-in 是全局类,它和任何组件都无绑定关系。BEM 要求动画修饰符必须表达「谁在动、处于什么状态」,而不是「怎么动」。比如 .modal--fade-in 明确表示「模态框正处于淡入过程中」,而 .fade-in 只是模糊的动效描述,加在 .card 上会覆盖错样式,加在 .toast 上又可能缺位移起点。
- 工具链(如 Stylelint)靠
--识别修饰符,.fade-in会被当成新 Block,校验失败 - CSS 选择器权重失控:
.fade-in优先级低于.modal__content,容易被覆盖 - JS 切类后无法精准控制时机——你删了
.fade-in,但不知道它原本属于哪个组件的动画流程
transition 和 animation 必须显式写在修饰符规则里
只加 .button--loading-spin 类,但 CSS 中没声明 transition 或 animation,动画就永远不会触发。浏览器不会自动补全属性,也不会继承父级的 transition: all。
- 禁止用
* { transition: all .2s }:它会让margin、color等非预期属性也过渡,且阻断will-change优化 - 每个修饰符必须完整声明:
.button--loading-spin { animation: loading-spin 0.4s linear infinite; } - 若用
transition(如高度展开),基础类.drawer就得先定义transition: max-height 0.3s ease,否则只展开有动画、收起直接跳变
多个动画状态如何共存而不嵌套
BEM 不允许 --loading--disabled 或 --fade-in--scale 这种链式修饰符。它们不是父子关系,而是并列布尔开关,应平级添加。
- 正确写法:
modal--fade-in modal--scale,CSS 中分别定义各自效果 - JS 控制时用
el.classList.toggle('modal--fade-in')和el.classList.toggle('modal--scale')独立操作 - 避免竞态:同一元素上频繁切换状态时,先调用
el.getAnimations().forEach(a => a.cancel())清理旧动画 - 入场/退出需分步:
add('card--fade-out')→ 等待animationend事件 →remove('card--fade-in')
最易被忽略的是:修饰符语义必须和组件强绑定,.card--fade-in 挪到 .modal 上就失效;动画的取消逻辑、硬件加速条件(是否用 transform)、事件过滤(只响应 event.animationName === 'fade-in'),全都依赖这个绑定关系成立。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











