【问题标题】:Is it possible to use animate.css with already translated elements?是否可以将 animate.css 与已翻译的元素一起使用?
【发布时间】:2020-04-20 20:46:50
【问题描述】:

我在一个网站上使用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));
}

看起来像这样:

单击 X 时,我将 animated fadeOutDown 添加到 divclassList。我希望元素从页面上的位置直接向下淡出。问题是,动画的工作方式如下......

@-webkit-keyframes fadeOutDown {
  from {
    opacity: 1;
  }

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

...所以我原来的变换规则被覆盖,元素在上图中蓝色箭头的方向淡出。

我的解决方法:

到目前为止,我发现克服这个问题的唯一方法是定义一个新类,其中包含我想要的翻译,并在 classList 中使用它...

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

...这行得通,但这意味着为我在元素上的每个不同转换为每个动画编写一个新规则!

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

【问题讨论】:

  • 对于特定的div,您可以使用left: 0; right: 0; width: 50%; bottom: 10px; margin: 0 auto; 来避免使用转换。但是,您也可以将元素包装在一个新的div 中,该div 将接收animate.css 转换。
  • 感谢@chriskirknielsen 的建议。但是,这仅在您在元素上指定宽度时才有效吗? div 根据上下文包含不同的文本,因此如果它的文本很少,我希望它足够大以包含内容,即不要在元素上设置width。跨度>
  • 您使用两个包装器制作元素,一个将获取您的动画,另一个将获取 animate.css
  • 您可以使用!important 为您的css 属性赋予优先级,这样它就不会被以下属性覆盖。或者在您使用fixed 位置的情况下,只需使用margin 而不是transform:translate
  • 我的answer below 有帮助吗?

标签: css css-animations animate.css


【解决方案1】:

说明

不幸的是,CSS 无法在没有明确告知的情况下知道元素之前的transform 值。话虽如此,您的问题有一个解决方法:只需明确告诉 CSS 初始 transform 值。

要使用纯 CSS 实现您想要的,我们可以使用 calc 函数来执行计算。除了calc,我们还将使用CSS custom properties显式声明初始变换值。然后,还要告诉 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

或者,正如您问题中的 cmets 所建议的那样,您可以添加另一个包装器,以便您可以应用两个转换值。

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>

【讨论】:

  • 谢谢@Richard 的回答。我已经运行了您的 sn-ps,它们在 Firefox 中运行良好,但是 foo 似乎只在 chrome 中的所有三个示例中淡出(没有向下移动)。你知道是什么阻止了它与 chrome 一起工作吗?
  • @compuphys 啊,Chrome 似乎不支持 CSS 属性 translate。您可以改用transform: translate(...)。我已经编辑了第一个 sn-p 以便它在 Chrome 中运行良好;-)
  • 感谢您。这是对 CSS 自定义属性的一个很好的使用。
  • @compuphys 很高兴我能帮上忙 ;-)
【解决方案2】:

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

你可以做的就是不要在你的固定元素上使用变换。尝试这样的事情,然后尝试将其淡出。

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

【讨论】:

    猜你喜欢
    • 2022-11-09
    • 1970-01-01
    • 2011-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多