具有负值的CSS转换延迟?

时间:2017-01-02 19:47:20

标签: javascript html css css3 css-transitions

我正在尝试理解CSS transition-delay属性的负值。请先查看代码示例。有两个div具有不同的转换延迟。

我认为给出延迟的负值与给权div0.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>

3 个答案:

答案 0 :(得分:22)

否定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>

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

答案 1 :(得分:5)

  

问:有人可以解释一下否定transition-delay值的作用吗?

根据transition-delay的{​​{3}}:

  

负值会导致转换立即开始,但会导致转换似乎从动画效果的中途开始。

MDN documentation中也提到了这一点,如W3C Working Draft for the property所述:

  

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

这意味着转换将立即开始并在中途开始,就像指定的时间已经过去一样。例如,请考虑这个(开放代码段):

#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处开始。负值也会从转换的持续时间中消失。 / p>

  

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

它们绝对有效,自第一个Alexander O' Mara's answer起一直有效。该属性允许所有时间值,并允许负值是其结果。

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

  

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

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

当您使用动画时,上面的尤其为true,与重复时的过渡相反。当您使用动画时,负延迟可以允许您跳转到动画的某些点,并允许跨多个共享行为的元素的重用能力,而不是时间。以下面的示例(找到Working Draft of CSS Transitions):

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会使圆圈在不同时间移动,进一步进入动画循环。

答案 2 :(得分:0)

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