You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现悬停显示内容且不改变卡片高度的平滑动画效果

实现悬停显示内容且不改变卡片高度的平滑动画效果

嘿,我来帮你搞定这个悬停卡片的平滑动画问题!先理清楚你的核心需求和遇到的痛点:

你的需求&痛点

你想要做一个卡片悬停效果:

  • 默认只显示基础内容,隐藏.hoverCard__showOnHover区域
  • 悬停时,隐藏内容平滑展开,同时卡片底部的内容区域向上平移,卡片整体高度完全不变

但实际开发中踩了几个坑:

  1. 用visibility: hidden/opacity: 0/height: 0隐藏内容时,元素还是会占空间,导致卡片底部多出一大块空白
  2. 用display: none虽然不占位,但切换时会让卡片突然“跳一下”,而且卡片高度会随内容展开变大,不符合预期
  3. 试了GSAP控制高度,也没解决这些问题

核心解决思路

要实现高度不变+平滑动画的效果,关键要抓住这几点:

  1. 把卡片底部的内容区(.hoverCard__body)设为绝对定位,固定在卡片底部,这样它平移时不会影响卡片整体高度
  2. 用max-height配合过渡动画来控制隐藏内容的显示/收起,替代display: none或height: 0,彻底避免跳跃
  3. 区分触摸设备和非触摸设备的交互,提升兼容性

完整可运行代码

HTML 结构

<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.0.2/css/bootstrap.min.css" rel="stylesheet">

<section>
  <div class="container">
    <div class="row">
      <div class="col-12 col-md-6">
        <article class="hoverCard position-relative">
          <div class="hoverCard__header">
            <!-- 这里放卡片头部图片 -->
          </div>
          <div class="hoverCard__body">
            <div class="hoverCard__body-text">Subheader</div>
            <div class="hoverCard__showOnHover">
              <p>This will show on hover Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
            </div>
          </div>
        </article>
      </div>
      <div class="col-12 col-md-6">
        <article class="hoverCard position-relative">
          <div class="hoverCard__header">
            <!-- 这里放卡片头部图片 -->
          </div>
          <div class="hoverCard__body">
            <div class="hoverCard__body-text">Subheader 2</div>
            <div class="hoverCard__showOnHover">
              <p>This will show on hover</p>
            </div>
          </div>
        </article>
      </div>
    </div>
  </div>
</section>

CSS 样式(优化版)

:root{
  --white: #FFFFFF;
  --black: #000000;
  --yellow: #FFE775;
}

section{
  padding: 150px 0;
}

.hoverCard {
  margin-bottom: 15px;
  width: 100%;
  border-radius: 8px;
  overflow: hidden;
  /* 固定卡片总高度,确保悬停时尺寸不变 */
  height: 530px;
  background-color: var(--black);
  color: var(--white);
  border: 1px solid var(--black);
  position: relative;
}

/* 针对非触摸设备的悬停交互 */
@media (hover: hover) {
  .hoverCard__body,
  .hoverCard__showOnHover {
    /* 用更自然的过渡曲线,动画更丝滑 */
    transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
  }

  .hoverCard:hover .hoverCard__body {
    transform: translateY(-75px);
  }

  .hoverCard:hover .hoverCard__showOnHover {
    /* 设置足够大的max-height,覆盖所有可能的内容高度 */
    max-height: 200px;
    opacity: 1;
  }
}

/* 触摸设备直接显示全部内容,避免悬停操作的不便 */
@media (pointer: coarse) {
  .hoverCard__showOnHover {
    max-height: none;
    opacity: 1;
    margin-bottom: 30px;
  }
}

.hoverCard__showOnHover {
  /* 默认隐藏:max-height为0 + 透明 */
  max-height: 0;
  opacity: 0;
  overflow: hidden;
}

.hoverCard__header {
  height: 350px;
  background-color: var(--yellow);
}

.hoverCard__body {
  /* 绝对定位固定在卡片底部 */
  position: absolute;
  bottom: 0;
  width: 100%;
  padding: 30px;
  color: var(--white);
  background-color: var(--black);
}

.hoverCard__body-text {
  margin-bottom: 20px;
}

关键优化点解释

  1. 固定卡片高度:给.hoverCard设置height: 530px,确保无论内容是否展开,卡片整体尺寸都不变
  2. 绝对定位内容区:.hoverCard__body绝对定位在底部,平移时不会触发布局重排,卡片高度不受影响
  3. max-height过渡:用max-height替代display: none或height: auto,让浏览器能识别动画的起始/结束状态,实现平滑展开/收起
  4. 设备适配:针对触摸设备直接显示全部内容,提升移动端用户体验
  5. 自然过渡曲线:用cubic-bezier(0.4, 0, 0.2, 1)替代默认的ease,动画更符合真实物理效果,不会生硬

你之前问的几个问题解答

Q: 如果隐藏内容的高度是动态未知的,怎么设置max-height?

A: 很简单,设置一个足够大的固定值就行(比如200px或500px),只要这个值大于你预期的最大内容高度。因为过渡动画是基于max-height的变化,即使实际内容高度比这个值小,动画依然会平滑执行,不会有问题。如果实在无法预估,也可以用JS动态计算内容高度后再设置,但一般来说固定足够大的值就够用了。

Q: 为什么之前的实现会有跳跃感?

A: 之前用display: none切换时,元素会瞬间从DOM中添加/移除,导致浏览器突然重排布局,产生跳跃;而height: auto时,浏览器无法计算过渡动画的起始和结束高度,也会出现跳跃。用max-height过渡则能让浏览器明确动画的范围,自然就平滑了。

备注:内容来源于stack exchange,提问作者Freddy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 15:55:32