如何为两个CSS类应用同一个keyframe动画名称并清理重复CSS代码
问题根因
这个问题和@keyframes本身能不能复用没有关系,核心是你的触发逻辑符合了浏览器跳过动画重放的规则:
- 你的代码中始终复用同一个
<div>容器元素,只是切换它的fullPage/halfPage类名,React默认不会销毁重建这个DOM节点,只是更新它的属性。 - 浏览器对CSS动画的触发逻辑是:如果同一个DOM元素已经执行过某名称的@keyframes动画,后续只要动画名称没有发生变化,即使切换类名,浏览器也会判定动画已经完成,不会重新触发执行。
- 你用两个不同名称的动画能生效,本质是每次切换类名时动画名称同步发生了变化,浏览器才会把它识别为新的动画重新执行。
优化方案(清理冗余keyframes)
你只需要保留1份fadeIn的@keyframes规则,通过修改触发逻辑让动画正常重放即可,最简便的实现方式如下:
方案:给容器绑定key属性,触发DOM重建
给承载组件的容器加上和显示状态绑定的key值,每次状态切换时React会自动销毁旧DOM、创建新的DOM节点,新节点会自动重新执行fadeIn动画,不需要多份冗余的keyframes定义。
修改后的TSX代码:
// App.tsx 仅需修改容器部分代码 export default function App() { const [cnt, setCnt] = useState(0); const isFullPage = cnt % 2 === 0; const appClass = classNames({ fullPage: isFullPage, halfPage: !isFullPage }); const handleOnClick = () => { setCnt(cnt + 1); }; return ( <div className="App"> <button onClick={handleOnClick}>Change background</button> {/* 新增key属性,值随显示状态变化 */} <div key={isFullPage ? 'full' : 'half'} className={appClass}> {isFullPage ? <FullPage /> : <HalfPage />} </div> </div> ); }
清理后CSS代码:
.fullPage { background-color: aquamarine; animation: fadeIn 2s linear; width: 490px; } .halfPage { background-color: bisque; animation: fadeIn 2s linear; width: 290px; } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
如果不想触发DOM重建,也可以通过临时移除动画类、强制浏览器重绘后再加回的方式触发动画重放,同样可以实现单份keyframes复用。
内容的提问来源于stack exchange,提问作者jacobcan118
相关产品推荐
相关产品推荐

