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

React中实现内容动态变化div的展开收起平滑过渡效果

动态内容展开/收起平滑过渡实现方案

针对高度为auto的动态CMS内容,有3种常用的无固定高度依赖的实现方案:

方案1:max-height 过渡(兼容性最好,无JS依赖)

该方案不需要提前知晓内容高度,仅需给容器设置一个远大于实际最大内容高度的max-height值,通过切换max-height的状态实现过渡:

  • 收起状态设置max-height: 短描述状态的实际高度,同时开启overflow: hidden,添加过渡属性transition: max-height 0.3s ease
  • 展开状态设置max-height: 远大于站点所有可能的描述内容高度的数值(比如1000px,根据业务场景调整即可)

注意点:如果预估的max-height和实际内容高度差太多,会出现过渡速度不一致的问题,适合内容长度浮动不大的场景。
示例代码:

.desc-container {
  overflow: hidden;
  max-height: 60px; /* 短描述状态的固定高度 */
  transition: max-height 0.3s ease;
}
.desc-container.expanded {
  max-height: 1000px; /* 确保大于站点所有可能的描述内容高度 */
}

方案2:CSS Grid 过渡(无高度预估,效果更丝滑)

该方案是近些年兼容性已经覆盖绝大多数用户的新方案,不需要预估高度,也可以纯CSS实现:

  • 给外层容器用grid布局,收起状态设置grid-template-rows: 0fr,内容会被自动压缩
  • 展开状态设置grid-template-rows: 1fr,同时给容器的子元素加min-height: 0避免内容溢出
  • 过渡属性绑定grid-template-rows即可
    示例代码:
.desc-wrapper {
  display: grid;
  grid-template-rows: 0fr;
  overflow: hidden;
  transition: grid-template-rows 0.3s ease;
}
.desc-wrapper.expanded {
  grid-template-rows: 1fr;
}
.desc-content {
  min-height: 0;
}

该方案对现代浏览器(Chrome 107+、Firefox 113+、Safari 16.1+)兼容性已经覆盖95%以上的用户,如果不需要兼容非常旧的浏览器优先选这个方案。

方案3:JS 动态计算高度(100%精准,无兼容问题)

如果内容长度浮动极大,又需要兼容旧浏览器,可以用JS动态读取内容的实际高度来设置:

  • 收起状态默认高度设为短描述的高度,CSS过渡属性绑定height
  • 点击切换展开时,先读取内容的scrollHeight,把height设为这个值,过渡完成后再改回auto(避免窗口resize时内容溢出)
  • 点击切换收起时,先把height从auto改成当前的scrollHeight,下一帧再改成短描述高度触发过渡
    示例代码:
const descEl = document.querySelector('.desc-container')
const toggleBtn = document.querySelector('.toggle-btn')

toggleBtn.addEventListener('click', () => {
  const isExpanded = descEl.classList.contains('expanded')
  if (isExpanded) {
    // 收起逻辑:先把auto改成当前实际高度
    descEl.style.height = descEl.scrollHeight + 'px'
    // 下一帧触发过渡到收起高度
    requestAnimationFrame(() => {
      descEl.style.height = '60px' // 短描述固定高度
      descEl.classList.remove('expanded')
    })
  } else {
    // 展开逻辑:设置为实际内容高度
    descEl.style.height = descEl.scrollHeight + 'px'
    descEl.classList.add('expanded')
    // 过渡完成后改回auto,适配窗口resize
    setTimeout(() => {
      descEl.style.height = 'auto'
    }, 300) // 和CSS过渡时长保持一致
  }
})
.desc-container {
  overflow: hidden;
  height: 60px; /* 短描述固定高度 */
  transition: height 0.3s ease;
}

内容的提问来源于stack exchange,提问作者David Fox

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 07:18:03