CSS 过渡、绝对定位和 React 过渡组有问题

Trouble with CSS transition, absolute positioning, and React Transition Group

我正在处理一些基本的 FreeCodeCamp 挑战,我正在尝试使用 React Transition Group 来实现一些非常简单的动画。这是 CodePen.

我 运行 的问题是我无法找到如何让 "quote card" 水平和垂直居中,以及我的动画(我正在使用 React过渡组触发)对其执行翻译。我有我要移动的元素 (#quote-box) 以以下 css:

为中心
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);

这是我在过渡组中使用的 "move" CSS classes:

.move-enter {
  opacity: 0.01;
  transform: translate(-200px, 0);
}

.move-enter-active {
  opacity: 1;
  transform: translate(0, 0);
  transition: all 500ms ease-in 200ms;
}

.move-exit {
  opacity: 1;
  transform: translate(0, 0);
}

.move-exit-active {
  opacity: 0.01;
  transform: translate(200px, 0);
  transition: all 500ms ease-in 200ms;
}

我假设我应该将 transition 属性设置为 left 而不是 all,但我有点迷失在阻止移动发生的原因上。我还应该有一个 move-exitedmove-entered class 适当的定位吗?提前致谢!

关于这里可能出了什么问题,有一个非常重要的提示,那就是在您的 CodePen 中,卡片成功地为它们的 opacity 而不是它们的 transform 设置了动画。这告诉你 something 正在按预期工作,只是不是 all 过渡。

因此,我们的第一步是调查发生的转变。事实上,如果我们将 CSS 过渡持续时间减慢到 20 秒并将 <ReactTransitionGroup.CSSTransition> 超时也设置为 20 秒,并在过渡发生时使用 devtools 检查元素 div#quote-box,我们会看到有点可疑:

您的 CSS 转换 属性 用于 #quote-box 正在覆盖转换组转换 属性 用于 .move-enter-active(正如预期的那样 - 请参阅 CSS selector specificity ) (您可以看出,因为 .move-enter-active 中的 transform 属性 被划掉了)。换句话说,您的 CSS 过渡组变换从未应用,但 opacity 过渡不受影响,因为 #quote-box 没有设置 属性.

这里有一些可能的解决方案。最简单的方法之一涉及两个步骤:

  1. #quote-box 从 ID 更改为 class (.quote-box) -(无论如何你都应该这样做,对于页面上的任何 ID 也是如此,因为你应该只在页面上曾经有一个相同命名 ID 的单个实例,并且使用 CSS 过渡组在某些时候你将至少有两个。)这也将确保你的 CSS 过渡组 .move-* 选择器将具有适当的优先级。
// CSS
.quote-box {
  // etc
}

// JSX
<div className="quote-box" >
  {/* etc */}
</div>
  1. 调整您的 CSS 以使用 calc() 函数计算报价框的位置。这是因为通常情况下,您无法同时使用 transform(-50%, -50%) 将引号框的位置偏移到 transform(-200px, 0) 的过渡位置。为此,我们必须使用 calc() 同时组合 居中变换 过渡偏移,即 transform: translate(calc(-50% - 200px), -50%);:
.move-enter {
  opacity: 0.01;
  transform: translate(calc(-50% - 200px), -50%);
}

.move-enter-active {
  opacity: 1;
  transform: translate(-50%, -50%);
  transition: all 500ms ease-in 200ms;
}

.move-exit {
  opacity: 1;
  transform: translate(-50%, -50%);
}

.move-exit-active {
  opacity: 0.01;
  transform: translate(calc(-50% + 200px), -50%);
  transition: all 500ms ease-in 200ms;
}

https://codepen.io/_jered/pen/KKPomVK