我正试图在Reaction中创建一个手风琴组件,使"Content"部分的打开和关闭流畅,以扩大高度.在一些在线教程的帮助下,我编写了下面的代码,一切似乎都运行得很好,但当内容div上的"关闭"过渡结束时,出现了明显的卡顿.它会平稳地打开,但再次单击会导致它以90%的速度平稳关闭,然后它会捕捉到关闭状态.为什么会这样,我该如何修复呢?

我想看看Layout属性是否有帮助,但在我的Accordion组件上设置它并没有改变任何行为.我想这可能与此有关,因为我是在为高度设置动画.我也不确定Height:Auto是否阻碍了动画的流畅.这个组件正用于一个Astro项目,带有client: loadprops .

import React, { useState } from "react";
import { motion, AnimatePresence } from "framer-motion";
import Arrow from "/FAQ_Arrow.svg"; // a chevron

export default function Accordion({ header, text }) {
  const [isOpen, toggleOpen] = useState(false);
  return (
    <div className="w-full border-2 border-gray-700 rounded-t-md rounded-md py-4 px-8 bg-white text-black">
      <button
        className="flex justify-between items-center w-full"
        onClick={() => toggleOpen(!isOpen)}
      >
        <h1 className="text-large md:text-2xl font-bold text-[#6130C9]">{header}</h1>
        <img
          src={Arrow}
          alt=""
          className={`transition-all duration-300 ${
            isOpen ? "-rotate-180" : ""
          }`}
        />
      </button>

      {/* Expanded text */}
      <AnimatePresence mode="sync">
        {isOpen && (
          <motion.div
            initial={{ height: 0 }}
            animate={{ height: "fit-content" }}
            exit={{ height: 0 }}
            transition={{duration: 0.3, type: "spring"}}
            className="text-base mt-4 overflow-hidden"
          >
            <h3>{text}</h3>
          </motion.div>
        )}
      </AnimatePresence>
    </div>
  );
}

我还做了一个基本的Astro代码和盒子来演示这个问题:https://codesandbox.io/p/sandbox/vigorous-breeze-d842q8

推荐答案

不久前我也遇到过类似的问题.似乎当框架运动计算要设置动画的高度/宽度时,它没有考虑填充、边距或边框宽度.Framer Motion的作者在this github issue讲了更多关于它的内容

您可以通过删除进入/离开DOM的元素的所有填充和页边距来修复它,并将其放在内部div上,如下所示:

<AnimatePresence mode="sync">
    {isOpen && (
      <motion.div
        initial={{ height: 0 }}
        animate={{ height: "fit-content" }}
        exit={{ height: 0 }}
        transition={{duration: 0.3, type: "spring"}}
        className="text-base overflow-hidden"
      >
        <div className="mt-4">
          <h3>{text}</h3>
        </div>
      </motion.div>
    )}
  </AnimatePresence>

Css相关问答推荐

如何获得特定位置的Divs以根据浏览器宽度正确调整大小

在ReactJS中使用动画在栅格上添加柱

Angular Material:如何同时使用2个徽章

不了解重复-线性-渐变 colored颜色 停止

Nuxt 3+sass:不能将包含路径与@IMPORT和@USE一起使用

如何使用 :has() 父 Select 器 Select 父元素的子元素,在父元素和子元素之间没有中间层的情况下?

SVG样式中的CSS类名是否是全局的?

如何在使用 bslib 5 的shiny 应用程序中使用样式参数排列 ui 元素

当您到达页面底部时,如何使页脚 div 将附加的 div 向上推

Material UI Modal 因背景而变暗

为什么这个绝对定位的 ::after 伪元素会崩溃,除非父级有过滤器?

使用 Webpack5 在 CSS 文件中内联字体和图像?

如何测试页面上的文本被删除

有没有办法让 mui v5 呈现没有 css-xxx 前缀的类名?

创建一条淡出/在各个方向变得透明的线

CSS类和id同名

我应该使用 CSS :disabled 伪类还是 [disabled] 属性 Select 器,还是见仁见智?

Flexbox 代码适用于除 Safari 之外的所有浏览器.为什么?

在 CSS3 中重新启动动画:比删除元素更好的方法吗?

如何将页脚(div)与页面底部对齐?