Vue.js Bootstrap卡片组件动画问题:点击卡片展开并平滑隐藏其他卡片
实现卡片平滑展开+其他卡片隐藏的动画效果
嘿,这个需求其实核心就是状态控制+CSS过渡动画的组合,我给你一步步拆解实现思路和代码:
1. 先搞定状态管理
首先你需要一个状态来记录当前被点击的卡片ID,这样才能区分哪个卡片要展开,哪些要隐藏。用React的useState就可以轻松实现:
const [selectedUserId, setSelectedUserId] = useState(null);
然后给每个卡片绑定点击事件,点击时切换选中状态(再次点击已选中的卡片就收起):
const handleCardClick = (userId) => { setSelectedUserId(prev => prev === userId ? null : userId); };
2. 动态控制卡片的类名与内容
接下来要给每个卡片容器动态分配类名:选中的卡片用col-12占满整行,未选中的用你原来的列宽(比如col-4)。同时,选中时展示详情内容,未选中时展示缩略内容:
<div className="row g-3"> {users.map(user => ( <div key={user.id} className={`card-container col ${selectedUserId === user.id ? 'col-12' : 'col-4'}`} onClick={() => handleCardClick(user.id)} > <div className="card h-100"> {selectedUserId === user.id ? ( // 用户详情内容 <div className="card-body"> <h5 className="card-title">{user.name}</h5> <p className="card-text">邮箱:{user.email}</p> <p className="card-text">电话:{user.phone}</p> {/* 更多详情字段 */} </div> ) : ( // 缩略内容 <div className="card-body"> <h5 className="card-title">{user.name}</h5> <p className="card-text">点击查看详情</p> </div> )} </div> </div> ))} </div>
3. 核心:CSS过渡动画实现平滑效果
这一步是关键,直接决定动画是否自然。我们需要给卡片容器添加过渡属性,同时处理未选中卡片的隐藏逻辑:
/* 给卡片容器添加过渡,让所有变化都平滑进行 */ .card-container { transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); overflow: hidden; } /* 当有卡片被选中时,隐藏其他未选中的卡片 */ /* 如果你需要兼容不支持:has选择器的浏览器,可以给row加个is-expanded类来替代 */ .row:has(.col-12) .card-container:not(.col-12) { opacity: 0; height: 0; padding: 0; margin: 0; border: none; }
这里的关键点:
- 不要用
display: none来隐藏卡片,因为display属性无法触发过渡动画,改用opacity和height的变化来实现平滑消失 - 用
cubic-bezier调整动画曲线,比默认的ease更自然 - 把padding、margin这些可能导致跳变的属性也加入过渡,避免动画过程中出现突兀的布局变化
兼容旧浏览器的小技巧
如果你的项目需要兼容不支持:has选择器的浏览器(比如旧版Chrome/Firefox),可以给row动态添加类名:
<div className={`row g-3 ${selectedUserId ? 'is-expanded' : ''}`}>
然后CSS改成:
.row.is-expanded .card-container:not(.col-12) { opacity: 0; height: 0; padding: 0; margin: 0; border: none; }
这样一套下来,就能实现点击卡片平滑展开至整行,同时其他卡片慢慢隐藏的效果啦~
内容的提问来源于stack exchange,提问作者artisan
相关产品推荐
相关产品推荐

