如何为MUI中隐藏的卡片添加平滑出现动画?
为隐藏的MUI卡片添加展开动画,避免突然弹出
问题分析
你当前的代码存在几个导致卡片突然弹出的问题:
- 使用
hidden属性直接隐藏元素,无过渡效果 - 自定义的
pop动画未定义关键帧 Collapse组件嵌套方式错误,未作用在卡片本身上
解决方案
以下是修改后的代码,通过MUI的Collapse组件结合自定义动画实现平滑展开效果:
import { makeStyles } from '@material-ui/core/styles'; import Box from '@material-ui/core/Box'; import Card from '@material-ui/core/Card'; import Collapse from '@material-ui/core/Collapse'; import IconButton from '@material-ui/core/IconButton'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; import { useState } from 'react'; const useStyles = makeStyles((theme) => ({ summaryBox: { display: 'flex', alignItems: 'center', }, qCard: { backgroundColor: '#D9F5FD', border: '1px solid #E1E1E1', width: '5vw', marginRight: '1vw', // 初始状态:透明+缩放缩小 opacity: 0, transform: 'scale(0.8)', // 自定义展开动画 animation: '$pop 500ms ease-in-out forwards', animationDelay: '100ms', }, // 定义pop动画关键帧 '@keyframes pop': { to: { opacity: 1, transform: 'scale(1)', }, }, expand: { transform: 'rotate(0deg)', marginLeft: 'auto', transition: theme.transitions.create('transform', { duration: theme.transitions.duration.shortest, }), }, expandOpen: { transform: 'rotate(180deg)', }, })); export default function ExpandableCard() { const classes = useStyles(); const [expanded, setExpanded] = useState(false); const handleExpandClick = () => { setExpanded(!expanded); }; return ( <Box className={classes.summaryBox}> {/* 用Collapse包裹整个Card,控制显示/隐藏 */} <Collapse in={expanded} timeout="auto" unmountOnExit> <Card className={classes.qCard}> {/* 卡片内容 */} </Card> </Collapse> <IconButton className={`${classes.expand} ${expanded ? classes.expandOpen : ''}`} onClick={handleExpandClick} aria-expanded={expanded} aria-label="展开更多" > <ExpandMoreIcon /> </IconButton> </Box> ); }
关键修改说明
- 移除冗余状态:不再需要
hidden状态,直接通过Collapse的in属性绑定expanded状态控制卡片显示 - 定义动画关键帧:添加
@keyframes pop实现淡入+缩放的平滑过渡效果 - 调整组件结构:将
Collapse作为Card的父组件,让折叠动画直接作用在卡片上 - 初始状态设置:给卡片设置初始的透明和缩小状态,动画触发后过渡到正常状态
替代方案(仅用MUI内置过渡)
如果不需要自定义缩放动画,仅用Collapse组件的默认高度过渡即可,简化样式:
const useStyles = makeStyles((theme) => ({ summaryBox: { display: 'flex', alignItems: 'center', }, qCard: { backgroundColor: '#D9F5FD', border: '1px solid #E1E1E1', width: '5vw', marginRight: '1vw', }, expand: { transform: 'rotate(0deg)', marginLeft: 'auto', transition: theme.transitions.create('transform', { duration: theme.transitions.duration.shortest, }), }, expandOpen: { transform: 'rotate(180deg)', }, })); // 组件部分不变,仅移除自定义动画相关样式
内容的提问来源于stack exchange,提问作者Ciaran Crowley
相关产品推荐
相关产品推荐

