如何使所有值的过渡持续时间相同?

How to make transition duration to be the same for all values?

我们有两个相似的宽度过渡,它们在中间被打断并且它们的最终过渡值发生了变化。 它们之间的唯一区别是绿色框的最终宽度与其起始宽度完全相同,而橙色框的最终宽度与其起始宽度不同。

这会使绿框过渡更快,就好像它只是在“撤消”初始过渡。

Link to a full demo

html:

<div id="reference"></div>
<div id="boxA" ></div>
<div id="boxB" ></div>

css:

#reference {
  width: 100px;
  height: 100px;
  background-color: rgba(0, 204, 255, 0.5);
}

#boxA {
  background-color: rgba(166, 255, 0, 0.5);
  height: 100px;
  transition: width 1s linear;
}

#boxB {
  background-color: rgba(255, 136, 0, 0.5);
  height: 100px;
  transition: width 1s linear;
}

javascript:

const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms))

document.getElementById("boxA").style.width = "100px";
document.getElementById("boxB").style.width = "100px";

(async () => {
await sleep(1000)

document.getElementById("boxA").style.width = "200px";
document.getElementById("boxB").style.width = "200px";

await sleep(500)

document.getElementById("boxA").style.width = "100px";
document.getElementById("boxB").style.width = "101px";

})()

这不是一个完美的答案,因为我无法告诉您每个不同元素的正确值,但它有效:

box1 = document.getElementById("boxA");
box2 = document.getElementById("boxB");

const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms))

box1.style.width = "100px";
box2.style.width = "100px";

(async() => {
  await sleep(1000)

  box1.style.width = "200px";
  box2.style.width = "200px";

  await sleep(500)

  box1.style.width = "100px";
  box2.style.transitionDuration = "0.5s";
  box2.style.width = "101px";

})()
#reference {
  width: 100px;
  height: 100px;
  background-color: rgba(0, 204, 255, 0.5);
}

#boxA {
  background-color: rgba(166, 255, 0, 0.5);
  height: 100px;
  transition: width 1s linear;
}

#boxB {
  background-color: rgba(255, 136, 0, 0.5);
  height: 100px;
  transition: width 1s linear;
}
<div id="reference"></div>
<div id="boxA"></div>
<div id="boxB"></div>

解释:两个box元素增加到200px,之后,第一个框回到100px,然而,第二个 box 元素仅减少 99px。由于它必须比第一个框覆盖更短的距离,因此它的 transition duration 也必须减少。

规范在这里:我会检查 §3.4.4 https://www.w3.org/TR/css-transitions-1/#starting

Otherwise, implementations must cancel the running transition and start a new transition whose:

...

  • reversing-adjusted start value is the same as the start value, and

因此,如果您 return 到原始值,那么它是相同的转换,但是要转到一个新值,它会从当前值开始一个新的转换。

所以绕过这个的一种方法是传入一个中间值,只是为了触发一个新的转换:

// go to any value (that is not the current value or the original value)
document.getElementById("boxA").style.width = "999px"; 

// Trigger reflow  (See @Kaiido's comment below)
 document.body.offsetWidth;

// and then immediately go back to the original value
document.getElementById("boxA").style.width = "100px";

现在两个框将有两个具有相同持续时间的过渡,但一个将在 100px 结束,另一个在 101px 结束。


另外我认为解释的理由是相关的:§3.1 Faster reversing of interrupted transitions