css modules中transition生效的关键是将其写在模块文件的本地类名规则内,而非全局样式;必须在常态选择器中定义transition,hover或active态仅定义属性变化值,且需确保目标属性在两态间存在差异。

transition写在CSS Modules的本地类名里才生效
CSS Modules会把.button编译成类似Button_button__abc123的唯一类名,但transition本身不关心类名是否被哈希——它只认最终渲染到DOM上的样式规则。所以只要transition声明写在模块文件里、且作用于该模块定义的类,就能正常工作。
常见错误是把transition写在全局样式或父组件的CSS中,结果子组件用CSS Modules引入的类没继承到过渡效果。本质不是“CSS Modules不支持transition”,而是作用域没对上。
- ✅ 正确:在
Button.module.css中直接写.button { transition: background-color 0.2s; } - ❌ 错误:在
global.css里写.button { transition: ... },然后期望它影响Button.module.css里的.button - ⚠️ 注意:
:global(.btn)这类穿透写法会绕过模块作用域,但容易污染全局,不推荐用于transition控制
hover动画必须同时定义常态和悬停态的transition
CSS Modules里:hover伪类和基础类是分开写的,但transition必须出现在常态选择器中,否则移出时没有过渡——这点和普通CSS完全一致,只是写的位置要落在同一个模块文件内。
例如,在Card.module.css中:
.card {
transform: scale(1);
transition: transform 0.25s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.card:hover {
transform: scale(1.08);
}
如果把transition只写在.card:hover里,鼠标移出就会硬切回原状。
- 必须显式写
transform: scale(1),不能省略,否则首次hover可能从无transform状态突变 - 避免用
transition: all,它会让padding/border等不可控属性也参与过渡,尤其在模块化组件中更难调试 - 多个模块共用同一套缓动函数?可以抽成CSS变量,比如
--ease-out-smooth: cubic-bezier(0.25, 0.46, 0.45, 0.94);,在各模块中引用
JS触发的class切换需注意模块类名拼接
React里用className={styles.active}给元素加类时,transition能否生效,取决于两个条件:一是styles.active对应的CSS规则里有没有transition,二是目标属性(如opacity或transform)是否在active态和常态之间有变化。
典型陷阱是:在模块中写了.active { opacity: 0; },但忘了在常态类(比如.item)里写transition: opacity 0.3s;,结果动画根本不跑。
- ✅ 推荐结构:
.item { opacity: 1; transition: opacity 0.3s; }+.item.active { opacity: 0; } - ❌ 不要依赖
!important强行覆盖transition,CSS Modules的哈希类优先级天然高于普通类,靠覆盖反而容易失控 - 动画结束需要回调?监听
transitionend事件时,事件对象的propertyName是实际触发过渡的属性名(如"opacity"),跟模块名无关
与keyframes动画混用时,避免同一属性重复声明
CSS Modules支持@keyframes,但要注意:如果某个属性(比如transform)既被transition控制,又被animation驱动,浏览器会以animation为准,transition会被忽略——这不是模块的问题,而是CSS层叠规则。
例如按钮抖动反馈场景,应该让animation负责一次性抖动,而transition负责背景色等其他属性的缓动,两者分工明确。
- ✅ 合理分工:
.btn { transition: background-color 0.3s; }+.btn.shake { animation: shake 0.5s; } - ❌ 危险写法:
.btn { transition: transform 0.3s; }和@keyframes shake { to { transform: translateX(10px); } }同时作用于transform,抖动会卡顿或失效 - JS移除
.shake类后,记得等animationend再操作DOM,否则可能打断transition流程
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











