【问题标题】:Absolutely positioned element moves after animation completes动画完成后绝对定位的元素移动
【发布时间】:2019-04-02 05:29:59
【问题描述】:

已经有一段时间了。无论如何,在制作动画时 让一个绝对定位的元素保持居中有些麻烦。更重要的是我在动画完成后看到元素“移位”,我不知道为什么。我发现的最接近的问题是css animations moves element position,但这并不能解决这个常见的用例。

调试动画帧,我们可以看到:

动画期间

动画之后

呸!玩定位没用,但是animation-fill-mode做了点什么;但是,我注意到translate 在动画期间或animation-fill-mode 设置为forwardsboth 时对定位元素没有影响。为什么?副作用是当动画完成时,元素的位置不会被重新计算,因此不会重新绘制。

例子:

<div class="alert alert-warning alert-dismissible fade show" role="alert">
  <strong>Holy guacamole!</strong> You should check in on some of those fields below.
  <button type="button" class="close" data-dismiss="alert" aria-label="Close">
    <span aria-hidden="true">&times;</span>
  </button>
</div>

以及使用 animate.css 的 CSS 让生活更轻松:

.alert {
  min-width: 500px;
  position: absolute;
  top: 0;
  left: 50%;
  animation-name: fadeInDown;
  animation-duration: 0.75s;
  animation-timing-function: ease-in-out;
  /* animation-fill-mode: forwards; */
  transform: translateX(-50%);
}

演示:https://codepen.io/atomicpages/pen/yrymVY?editors=1100

目标:

  1. 居中对齐
  2. 元素至少 500px
  3. 动画帧完成后元素不移动

感谢您的帮助。

【问题讨论】:

  • 不,我们在代码示例中提供的约束范围内操作。

标签: html css animation css-animations


【解决方案1】:

使用不带animate.css 的自定义fadeInDown,因为它在fadeIndown 中使用transform: translate3d(0, -100%, 0)

.alert {
  width: 500px;
  top: 0;
  left: 50%;
  animation-name: fadeInDown;
  animation-duration: 0.75s;
  animation-timing-function: ease-in-out;
  animation-fill-mode: forwards;
  transform: translateX(-50%);
  position:absolute;
}

@keyframes fadeInDown{
  from{
    opacity:0;
  }
  to{
    opacity:1;
  }
}

@-webkit-keyframes fadeInDown{
  from{
    opacity:0;
  }
  to{
    opacity:1;
  }
}
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" />
<div class="alert alert-warning alert-dismissible fade show" role="alert">
  <strong>Holy guacamole!</strong> You should check in on some of those fields below.
  <button type="button" class="close" data-dismiss="alert" aria-label="Close">
    <span aria-hidden="true">&times;</span>
  </button>
</div>

【讨论】:

  • 妈妈咪呀!我应该看看animate.css
【解决方案2】:

尝试去掉transform: translateX,动画结束后,元素原地不动,改为left: 0;

.alert {
  min-width: 500px;
  top: 0;
  left: 0;
  animation-name: fadeInDown;
  animation-duration: 0.75s;
  animation-timing-function: ease-in-out;
}

【讨论】:

  • 这违背了元素居中的目的
  • 不是吗?我看到元素居中,动画后它既不在左边也不在右边?请进一步解释它是居中的
  • 举个例子
  • left: 30% 不会在视口大小变化时保持元素居中
  • 您是否更喜欢将文本居中对齐?
【解决方案3】:

原因是内置的fadeInDown 也使用transform 作为其动画,因此重置/覆盖您的初始值,然后恢复它,除非您使用animation-fill-mode: forwards;,这将保持 50% 的折扣一直在左边。

请注意,预设transform“值”,如translateX,在将另一个“值”添加到“属性”时不会持续存在,所有现有值都会被覆盖。

原始 CSS

@keyframes fadeInDown {
  from {
    opacity: 0;
    -webkit-transform: translate3d(0, -100%, 0);
    transform: translate3d(0, -100%, 0);
  }

  to {
    opacity: 1;
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
  }
}

为了您的工作,您需要覆盖内置的,将您的 translateX 值添加到它,它会运行。

如果你这样做了,还有一个前缀 @keyframes 规则,也需要更新。

新的 CSS

@keyframes fadeInDown {
  from {
    opacity: 0;
    -webkit-transform: translate3d(-50%, -100%, 0);
    transform: translate3d(-50%, -100%, 0);
  }

  to {
    opacity: 1;
    -webkit-transform: translate3d(-50%, 0, 0);
    transform: translate3d(-50%, 0, 0);
  }
}

附注:

使用提供的设置,它将始终采用全宽并居中它不会有任何效果,除非您还在其他地方给它一个 max-width

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-29
    • 1970-01-01
    • 1970-01-01
    • 2012-07-06
    • 2018-04-22
    • 2021-01-28
    • 1970-01-01
    • 2014-05-02
    相关资源
    最近更新 更多