动画类名必须是--modifier,不能独立为.fade-in;须绑定具体组件如.modal--fade-in,语义表达“谁在动、什么状态、意图为何”,且css中必须显式声明animation/transition规则。

动画类名必须是--modifier,不能独立存在
直接写.fade-in或.slide-up是错的——它不是BEM里的修饰符,而是个无上下文的全局类。浏览器不认语义,只认选择器;工具链(如Stylelint)会把它当新Block,校验失败;JS加了类也找不到对应CSS规则。
正确写法是绑定到具体组件:.modal--fade-in、.card--expand-open、.spinner--rotating-medium。每个类名都回答三个问题:谁在动?处于什么状态?意图是什么?
-
.modal--fade-in表示“模态框当前正在淡入”,不是“所有东西都能淡入” -
.spinner--rotating-medium把行为(rotating)和节奏(medium)打包成一个可复用单元,避免.spinner--medium这种孤立修饰符 - 禁止
.btn--loading--fast这类双连字符嵌套——BEM解析器会当成一个新Block,语义断裂,也无法被插件识别
每个--modifier必须显式声明animation或transition
只加class="button--loading-spin"但CSS里没写transition或animation,动画永远不会触发。浏览器不会继承、不会补全、也不会猜你想要什么动效。
PigX UI Pro 前端开发指南 - Vue 3 + TypeScript + Element Plus。当用户提到 PigX UI、PigX 前端、lgb-mgui 项目、Vue 3 企业级后台开发、Element Plus 后台开发时使用此技能。
- 用
transition时,基础类就得先定义:.drawer { transition: max-height 0.3s ease; },否则只展开有动画,收起直接跳变 - 用
animation时,修饰符规则里必须配对:.modal--fade-in { animation: modal-fade-in 0.25s ease-out forwards; } - 禁用
* { transition: all .2s }——它会让margin、color等非预期属性也过渡,且阻断will-change优化
多个动画状态要平级组合,不能嵌套或拼接
BEM不承认--loading--disabled这种链式修饰符。它们不是父子关系,而是并列开关。JS控制时得独立增删,CSS里分别定义效果。
- 正确写法:
modal--fade-in modal--scale,两个类同时存在,互不干扰 - JS操作用
el.classList.toggle('modal--fade-in')和el.classList.toggle('modal--scale')分开调用 - 避免字符串拼接生成
class="modal--fade-in--scale"——这会被解析为单个非法Block,样式失效,工具链报错 - 入场/退出需分步:先加
card--fade-out→监听animationend→再删card--fade-in,否则竞态导致视觉错乱
修饰符命名要表达意图,而非视觉参数
--fade-200ms、--slide-left-40px、--red都是反模式。数值和颜色会变,但组件状态不会变。命名一旦绑定具体参数,换主题、适配移动端、做A/B测试时就得全局搜索替换。
- 用
--spinning-fast代替--fast:明确行为(spinning)+节奏(fast),不暴露毫秒值 - 用
--fading-out代替--fade-out:强调“正在退出”的过程态,而非静态结果 - 避免
--fetching这类后台状态词:BEM修饰符必须对应可感知的UI表现,而不是网络请求是否完成 - 动画关键帧名(
@keyframes)和修饰符名保持一致最稳妥:@keyframes modal-fade-in↔.modal--fade-in,JS不用额外映射
最容易被忽略的是:修饰符语义必须和组件强绑定。挪个类名过去就失效——.card--fade-in加到.modal上,CSS规则压根不匹配;JS清理动画、判断事件、触发硬件加速,全都依赖这个绑定成立。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










