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

为何显示与隐藏div时ease过渡动画出现速度异常?

解决手风琴组件过渡动画后期变慢的问题

问题根源在于你用max-height: 500px做过渡时,这个值远大于答案内容的实际高度。关闭动画时,当内容高度从实际值降到0后,max-height还在继续从实际高度往0过渡,这段时间视觉上已经没有变化,但动画仍在运行,所以会感觉后期变慢;打开时同理,只是从0到实际高度的阶段有视觉变化,之后到500px的阶段无感知,所以不明显。

以下是两种可行的解决方案:

方案1:动态计算实际内容高度(精确控制)

通过JS获取每个答案的真实高度,用CSS变量传递给样式,让max-height精确匹配内容高度,避免无效过渡。

React代码示例:

import { useEffect, useState } from 'react';

const Accordion = ({ items }) => {
  const [activeIndex, setActiveIndex] = useState(null);
  const [answerHeights, setAnswerHeights] = useState({});

  // 计算每个答案的真实高度
  useEffect(() => {
    const heights = {};
    items.forEach((_, index) => {
      const el = document.getElementById(`answer-${index}`);
      if (el) heights[index] = `${el.scrollHeight}px`;
    });
    setAnswerHeights(heights);
  }, [items]);

  const toggleAccordion = (index) => {
    setActiveIndex(prev => prev === index ? null : index);
  };

  return (
    <div className="accordion-container">
      {items.map((item, index) => (
        <div key={index} className="accordion-item">
          <div className="question" onClick={() => toggleAccordion(index)}>
            {item.Question}
          </div>
          <div
            id={`answer-${index}`}
            className={`answer ${activeIndex === index ? 'active' : ''}`}
            style={{ '--actual-height': answerHeights[index] || '0px' }}
          >
            {item.Answer}
          </div>
        </div>
      ))}
    </div>
  );
};

CSS调整:

.answer {
  max-height: 0;
  overflow: hidden;
  margin-left: 5rem;
  transition: max-height 0.7s ease-in-out;
}

.answer.active {
  padding-bottom: 2rem;
  max-height: var(--actual-height);
}

方案2:用CSS Grid替代max-height(纯CSS方案)

利用grid-template-rows的过渡特性,默认设为0fr(隐藏内容),激活时设为1fr(自适应内容高度),无需JS计算,动画更自然。

CSS代码:

.answer {
  display: grid;
  grid-template-rows: 0fr;
  overflow: hidden;
  margin-left: 5rem;
  transition: grid-template-rows 0.7s ease-in-out;
}

/* 给答案内容套内层div,确保grid能正确收缩 */
.answer > .content {
  min-height: 0;
}

.answer.active {
  padding-bottom: 2rem;
  grid-template-rows: 1fr;
}

对应HTML结构调整:

<div className={`answer ${activeIndex === index ? 'active' : ''}`} >
  <div className="content">{item.Answer}</div>
</div>

两种方案各有优劣:方案1适合内容高度变化频繁的场景,精度更高;方案2纯CSS实现,代码更简洁,兼容性覆盖绝大多数现代浏览器。

内容的提问来源于stack exchange,提问作者Sinister Pear

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 23:18:22