是否可以将animate.css与已翻译的元素一起使用?

时间:2020-04-20 20:46:50

标签: css css-animations animate.css

我在网站上使用Daniel Eden's animate.css。效果很好,但是我对已经应用了transform:translate()的元素遇到了问题。

我遇到的问题:

我有一个固定在页面底部的div,它在x方向上转换了-50%,在y方向上转换了-100%,以使其居中:

#resend_activation_div {
  position:fixed;
  top:100%;
  left:50%;
  transform:translate(-50%, calc(-100% - 10px));
}

如下所示: enter image description here

单击X时,我将animated fadeOutDown添加到classList的{​​{1}}中。我希望元素从其在页面上的位置直接向下淡出。问题是,动画以以下方式工作...

div

...因此我的原始转换规则被覆盖,并且该元素沿上图中的蓝色箭头方向淡出。

我的解决方法:

到目前为止,我发现唯一克服此问题的方法是定义一个新类,该类中包含我想要的翻译,并在@-webkit-keyframes fadeOutDown { from { opacity: 1; } to { opacity: 0; -webkit-transform: translate3d(0, 100%, 0); transform: translate3d(0, 100%, 0); } } 中使用它,而不是...

classList

...可行,但这意味着为我对元素进行的每个不同变换的每个动画编写新规​​则!

所以我的问题是:是否有更聪明的方法来做到这一点?在动画规则中执行转换时,可以让CSS尊重我的原始转换吗?

2 个答案:

答案 0 :(得分:2)

说明

不幸的是,CSS无法在没有明确告知的情况下知道元素以前具有的transform值。话虽这么说,但是您可以通过以下方法解决此问题:只需将CSS的初始transform初始值明确告知

要使用纯CSS实现您想要的功能,我们可以使用CSS custom properties函数执行计算。与calc一起,我们还将使用OAuth 2.0 On-Behalf-Of flow显式声明初始转换值。然后,还告诉CSS进行淡出动画所需的translateY(例如30px)的值。由于calc可用于操作CSS自定义属性,因此我们现在可以计算所需的结尾translate值(例如translate: 0px calc(var(--initial-transformY) + var(--added-transformY)))。将所有这些操作放在一个类中(例如.fadeOutDown),我们现在可以简单地将此类添加到要淡出的任何元素中。


解决方案#1

这里有一个示例,展示了如何一起使用CSS自定义属性和calc来实现所需的功能。在此示例中,您可以简单地向要淡出的元素添加fadeOutDown类(不使用animation属性)。该类将通过固定值translateY添加30px值(如果需要,您也可以使用CSS自定义属性)。

const foo = document.querySelector('.foo')
const bar = document.querySelector('.bar')

bar.addEventListener('click', e => {
  foo.classList.toggle('fadeOutDown')
})
* {
  box-sizing: border-box;
  font-family: Helvetica;
}

html,
body {
  width: 100%;
  height: 100%;
  margin: 0;
  overflow: hidden;
}

.foo {
  --initial-transformY: -10px;
  position: absolute;
  bottom: 0;
  left: 50%;
  width: 40%;
  background: #121212;
  color: white;
  border-radius: 5px;
  padding: 16px;
  text-align: center;
  transform: translate(-50%, var(--initial-transformY));
  /* or for Firefox, you can also use this -> translate: -50% var(--initial-transformY);*/
  transition:
    transform .5s ease,
    opacity .5s ease;
}

.fadeOutDown {
  opacity: 0;
  transform: translate(-50%, calc(var(--initial-transformY) + 30px));
  /* or for Firefox, you can also use this -> translate: -50% calc(var(--initial-transformY) + 30px) */
  /* Or you can use a CSS custom property like this (Firefox)
  --fadeOutDown-value: 30px;
  translate: -50% calc(var(--initial-transformY) + var(--fadeOutDown-value)); */
}

.bar {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  padding: 16px;
  background: #ad17fd;
  color: white;
  border: none;
  cursor: pointer;
  border-radius: 5px;
  transition: all .2s ease;
  text-transform: uppercase;
}
<div class="foo">Hello there, I am foo</div>
<button class="bar">Click me to move foo</button>

下面是使用animation属性的示例。我不建议使用此动画,因为反转动画是即时的(您可以使其逐渐显示,但这是额外的工作)。 transitiontransform一起使用更容易(上述方法)。

const foo = document.querySelector('.foo')
const bar = document.querySelector('.bar')

bar.addEventListener('click', e => {
  foo.classList.toggle('fadeOutDown')
})
@keyframes fadeOutDown {
  from {}
  to {
    opacity: 0;
    translate: var(--initial-transformX) calc(var(--initial-transformY) + 30px);
  }
}

* {
  box-sizing: border-box;
  font-family: Helvetica;
}

html,
body {
  width: 100%;
  height: 100%;
  margin: 0;
  overflow: hidden;
}

.foo {
  --initial-transformX: -50%;
  --initial-transformY: -10px;
  position: absolute;
  bottom: 0;
  left: 50%;
  width: 40%;
  background: #121212;
  color: white;
  border-radius: 5px;
  padding: 16px;
  text-align: center;
  translate: var(--initial-transformX) var(--initial-transformY);
}

.fadeOutDown {
  animation: .5s ease 0s fadeOutDown forwards;
}

.bar {
  position: absolute;
  top: 50%;
  left: 50%;
  translate: -50% -50%;
  padding: 16px;
  background: #ad17fd;
  color: white;
  border: none;
  cursor: pointer;
  border-radius: 5px;
  transition: all .2s ease;
  text-transform: uppercase;
}
<div class="foo">Hello there, I am foo</div>
<button class="bar">Click me to move foo</button>


解决方案2

或者,按照问题注释的建议,您可以添加另一个包装器,以便可以应用这两个变换值。

const foo = document.querySelector('.foo')
const bar = document.querySelector('.bar')

bar.addEventListener('click', e => {
  foo.classList.toggle('fadeOutDown')
})
* {
  box-sizing: border-box;
  font-family: Helvetica;
}

html,
body {
  width: 100%;
  height: 100%;
  margin: 0;
  overflow: hidden;
}

.wrapper {
  --initial-transformY: -10px;
  position: absolute;
  bottom: 0;
  left: 50%;
  width: 40%;
  color: white;
  text-align: center;
  translate: -50% -10px;
}

.foo {
  width: 100%;
  background: #121212;
  padding: 16px;
  border-radius: 5px;
  transition: translate .5s ease, opacity .5s ease;
}

.fadeOutDown {
  opacity: 0;
  translate: 0px 30px;
}

.bar {
  position: absolute;
  top: 50%;
  left: 50%;
  translate: -50% -50%;
  padding: 16px;
  background: #ad17fd;
  color: white;
  border: none;
  cursor: pointer;
  border-radius: 5px;
  transition: all .2s ease;
  text-transform: uppercase;
}
<div class="wrapper">
  <div class="foo">Hello there, I am foo</div>
</div>
<button class="bar">Click me to move foo</button>

答案 1 :(得分:0)

有一个小技巧可以尝试,尽管我很确定它会为您服务。在这种类型的元素中,位置固定,而不是全部固定。 您遇到的问题是由于您使用了transform属性,因为animate.css进行的转换会覆盖您的代码。

您可以做的是根本不对固定元素使用transform。尝试这样的事情,然后尝试淡出它。

`#resend_activation_div {
    position:fixed;
    top:100%;
    left:50%;
    margin-top: -10px;
    maergin-left: -(width of your element/2)px; // half of your element.
}` 
相关问题