【问题标题】:CSS transition-delay with a negative value?CSS转换延迟具有负值?
【发布时间】:2017-05-16 21:31:36
【问题描述】:

我试图理解 CSS transition-delay 属性的负值。请先看代码示例。有两个divs 有不同的转换延迟。

我认为为延迟提供负值与为右 div (0.2s) 提供正值相同,但它的行为不同。我认为它不会为0.2s 绘制,这会使转换变得跳跃。

  • 谁能解释一下负值transition-delay 的作用是什么?
  • transition-delay 的负值是否有效,或者不应该使用它们?
  • 如果可以使用它们,什么是好的用例?

function toggle() {
  var left = document.querySelector('.left');
  var right = document.querySelector('.right');
  left.classList.toggle('hidden');
  right.classList.toggle('hidden');
  left.classList.toggle('show');
  right.classList.toggle('show');
}
window.setInterval(toggle, 1500);
window.setTimeout(toggle, 100);
#container {
  background: yellow;
  display: flex;
  width: 200px;
  height: 200px;
  overflow: hidden;
}
.left,
.right {
  flex: 1;
}
.left {
  background: red;
  transition: transform 1s -0.2s cubic-bezier(0.19, 1, 0.22, 1);
}
.right {
  background: blue;
  transition: transform 1s cubic-bezier(0.19, 1, 0.22, 1);
}
.hidden {
  transform: translateY(100%);
}
.show {
  transform: translateY(0%);
}
.container-hide {
  transform: translateY(-100%);
}
<div id="container">
  <div class="left hidden"></div>
  <div class="right hidden"></div>
</div>

【问题讨论】:

  • developer.mozilla.org/en-US/docs/Web/CSS/transition-delay 说“负值会导致过渡立即开始,但会导致过渡似乎在动画效果的中途开始。
  • 如果您阅读了transition-delay 的万维网联盟 (W3) 文档,这可能会回答您的问题。
  • “负值导致过渡立即开始”既然这么说,过渡总是有一些延迟?
  • 否 - 零值(或缺少 transition-delay)也会导致转换立即开始。
  • 你可以说,负值会在 0 之前开始动画,但动画是隐藏的,直到值点过去。

标签: javascript html css css-transitions


【解决方案1】:

一个否定的transition-delay其实是完全有效的,和0s有不同的含义,和一个肯定的延迟也不一样。

摘自W3C Working Draft for transition-delay

如果transition-delay 的值为负时间偏移,则转换将在属性更改时执行,但似乎已在指定偏移处开始执行。也就是说,过渡似乎是在其播放周期的中途开始的。如果转换具有隐含的起始值和负的transition-delay,则起始值从属性更改的那一刻开始获取。

结果是动画的第一部分将被跳过。基本上,开始时间会发生偏移,从而改变动画上的计算点。

因此,如果 10s 持续时间动画有 -5s 延迟,它会出现在中途开始(跳过前半部分),并且仅在 5s 中完成。下面是一个简单的例子来展示这个效果。

说明性示例:

function toggle() {
  var left = document.querySelector('.left');
  var right = document.querySelector('.right');
  left.classList.toggle('hidden');
  right.classList.toggle('hidden');
  left.classList.toggle('show');
  right.classList.toggle('show');
}
window.setInterval(toggle, 15000);
window.setTimeout(toggle, 100);
#container {
  background: yellow;
  display: flex;
  width: 200px;
  height: 200px;
  overflow: hidden;
}
.left,
.right {
  flex: 1;
}
.left {
  background: red;
  transition: transform 10s linear;
  transition-delay: -5s;
}
.right {
  background: blue;
  transition: transform 10s linear;
  transition-delay: 0s;
}
.hidden {
  transform: translateY(100%);
}
.show {
  transform: translateY(0%);
}
.container-hide {
  transform: translateY(-100%);
}
<div id="container">
  <div class="left hidden"></div>
  <div class="right hidden"></div>
</div>

实际上没有任何理由必须避免使用负持续时间值,因为它们是有效的,它们只是有一个非常有限的用例。

【讨论】:

  • 这是我一直在寻找的答案。有一些关于负值转换的文档,但无法完全理解。现在我明白了!
【解决方案2】:

问:谁能解释一下负值transition-delay 的作用是什么?

根据MDN documentationtransition-delay

负值会导致过渡立即开始,但会导致过渡似乎在动画效果的中途开始。

这在W3C Working Draft for the property 中也有描述,如Alexander O' Mara's answer 所述:

如果transition-delay 的值是负时间偏移,则转换将在属性更改时执行,但似乎已在指定偏移处开始执行。也就是说,过渡似乎是在其播放周期的中途开始的。在转换具有隐含起始值和负转换延迟的情况下,起始值从属性更改的那一刻开始获取。

这意味着过渡将立即开始并在中途开始,就好像指定的时间已经过去一样。例如,考虑这个(打开 sn-p):

#box1 {
  width: 200px;
  height: 50px;
  
  transition: width 3s 1s;
    
  background-color: green;
}

#box2 {
  width: 200px;
  height: 50px;
  
  transition: width 3s 0s;
    
  background-color: red;
}

#box3 {
  width: 200px;
  height: 50px;
  
  transition: width 3s -1s;
    
  background-color: blue;
}


#box1:hover, #box2:hover, #box3:hover {
  width: 400px;
}
<div id="box1"></div>
<div id="box2"></div>
<div id="box3"></div>

<ul>
  <li>Box 1 (green) has transition delay of 1s.</li>
  <li>Box 2 (red) has transition delay of 0s.</li>
  <li>Box 3 (blue) has transition delay of -1s.</li>
<ul>  

您可以看到蓝色框(转换延迟为-1s 的那个)有点跳动。这是因为过渡立即开始,并且在过渡的中途开始,好像过渡应该开始已经过去了 1 秒

基本上,属性transition-delay 的负值使转换在|x|x 的绝对值)时间之后的转换位置开始,其中x 是属性的指定值。因此,如果我们为延迟指定 -1s,则转换将立即开始,并将在转换本来位于 1s in 的位置开始。负值也会影响转换的持续时间。


问:transition-delay 的负值是否有效,还是不应该使用?

它们是绝对有效的,并且从第一个Working Draft of CSS Transitions 开始就一直有效。该属性允许所有时间值,因此允许负值。

由于transition-delay 定义的行为将转换延迟某个偏移量,因此负值会跟随负值偏移量。反过来,这会导致动画在中途开始,就好像指定时间的绝对值已经过去了。


问:如果可以使用它们,什么是好的用例?

很难为这种效果勾勒出一个具体的用例,因为它不经常使用并且使用非常有限。我认为潜在的潜在用途可能是通过在转换周期中跳转到不同的状态来重用转换。

当您使用动画时,上述情况尤其是正确,这与重复的过渡相反。当您使用动画时,负延迟可以让您跳转到动画的某些点,并允许在共享行为的多个元素之间重用能力,而不是时间。举个例子(找到here):

div {
  border-radius:50%;
  position:absolute;
  top:50%; left:75%;
}
div:nth-of-type(odd) { background:black; }
div:nth-of-type(even) { background:white; border:2px solid black; }
div:nth-of-type(11) {
  height:10px; width:10px;
  margin-top:-5px; margin-left:-5px;
  -webkit-animation:slide 3s ease-in-out infinite;
  animation:slide 3s ease-in-out infinite;
}
div:nth-of-type(10) {
  height:20px; width:20px;
  margin-top:-12px; margin-left:-12px;
  -webkit-animation:slide 3s -2.7s ease-in-out infinite;
  animation:slide 3s -2.7s ease-in-out infinite;
}
div:nth-of-type(9) {
  height:40px; width:40px;
  margin-top:-20px; margin-left:-20px;
  -webkit-animation:slide 3s -2.4s ease-in-out infinite;
  animation:slide 3s -2.4s ease-in-out infinite;
}
div:nth-of-type(8) {
  height:60px; width:60px;
  margin-top:-32px; margin-left:-32px;
  -webkit-animation:slide 3s -2.1s ease-in-out infinite;
  animation:slide 3s -2.1s ease-in-out infinite;
}
div:nth-of-type(7) {
  height:80px; width:80px;
  margin-top:-40px; margin-left:-40px;
  -webkit-animation:slide 3s -1.8s ease-in-out infinite;
  animation:slide 3s -1.8s ease-in-out infinite;
}
div:nth-of-type(6) {
  height:100px; width:100px;
  margin-top:-52px; margin-left:-52px;
  -webkit-animation:slide 3s -1.5s ease-in-out infinite;
  animation:slide 3s -1.5s ease-in-out infinite;
}
div:nth-of-type(5) {
  height:120px; width:120px;
  margin-top:-60px; margin-left:-60px;
  -webkit-animation:slide 3s -1.2s ease-in-out infinite;
  animation:slide 3s -1.2s ease-in-out infinite;
}
div:nth-of-type(4) {
  height:140px; width:140px;
  margin-top:-72px; margin-left:-72px;
  -webkit-animation:slide 3s -0.9s ease-in-out infinite;
  animation:slide 3s -0.9s ease-in-out infinite;
}
div:nth-of-type(3) {
  height:160px; width:160px;
  margin-top:-80px; margin-left:-80px;
  -webkit-animation:slide 3s -0.6s ease-in-out infinite;
  animation:slide 3s -0.6s ease-in-out infinite;
}
div:nth-of-type(2) {
  height:180px; width:180px;
  margin-top:-92px; margin-left:-92px;
  -webkit-animation:slide 3s -0.3s ease-in-out infinite;
  animation:slide 3s -0.3s ease-in-out infinite;
}
div:nth-of-type(1) {
  height:200px; width:200px;
  margin-top:-100px; margin-left:-100px;
  -webkit-animation:slide 3s ease-in-out infinite;
  animation:slide 3s ease-in-out infinite;
}
@keyframes slide {
  0% { left:75% }
  50% { left:25%; }
  100% { left:75%; }
}
@-webkit-keyframes slide {
  0% { left:75% }
  50% { left:25%; }
  100% { left:75%; }
}
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>

在这里,负animation-delay 值通过跳转到动画循环中的不同状态来使用。所有圆圈都有相同的行为,通过来回移动,但时间不同,因为它们模拟了一个波浪。负值animation-delay 使圆圈在不同时间移动,进一步进入动画循环。

【讨论】:

    【解决方案3】:

    负转换会从转换时间中减去,但不会超过 0。

    【讨论】:

      猜你喜欢
      • 2015-04-18
      • 2015-12-05
      • 2015-07-01
      • 2017-03-28
      • 2017-09-05
      • 2014-07-10
      • 2014-10-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多