4

可以在这里看到一个活生生的例子。

红色方块(显示)直接位于绿色方块上方(隐藏为溢出)。单击正方形,两个彩色正方形立即变得完全透明。另外,红色方块的高度设置为0;这会触发一个过渡,但由于红色方块现在是透明的,所以过渡看不到。

在再次单击方块之前,检查toggle函数。查看 JavaScript,我希望红色方块的高度在不触发转换的情况下重置为其原始值。应该抑制过渡,因为在none更改高度时临时设置了过渡属性。

现在再次单击正方形。两个彩色方块都会立即变得完全不透明,但红色方块会随着高度从 0 过渡到原始值而向下滑动。就好像在toggle元素可见之前,函数不会删除内联样式设置的高度,到那时,过渡属性也已被重置。

触发回流似乎会强制应用高度变化。(取消注释包含offsetParent要测试的行。)这种行为发生在浏览器(至少 Chrome 和 Safari、Firefox 和 Opera)中,所以我想知道它是否不是某些规范的一部分。我检查了CSS 过渡模块但没有成功。任何想法为什么会发生这种行为,以及为什么它在实现之间如此一致?

4

1 回答 1

4

这确实是一个奇怪的问题。我不认为你在代码中做错了什么——当前的浏览器实现只是有缺陷。

在使用 CSS 转换之前,我遇到过这些看似显而易见的错误,如果不诉诸拜占庭式的黑客攻击,一旦他们正在解决的错误被修复,它们肯定会被破坏(在这个情况下,我的 WebKit 修复)。

我确实对此进行了深入研究,但无法提出一个干净的解决方案,该解决方案适用于三个主要的过渡支持布局引擎(WebKit、Gecko 和 Presto)。也就是说,这就是我所发现的——希望比我更聪明的人(或者只是以新的眼光来看待这个问题)可以接受这个答案并将其转化为真正的解决方案。

Gecko 和 Presto(但不是 WebKit!)

看起来(我不是浏览器工程师或熟悉规范)任何当前或以前的 a 值都transition-property将继续呈现,无论它是否需要。因此,即使您更改了 的值transition-property,浏览器仍会在后台渲染高度过渡,并且当您将高度更改回来时,您会得到它的尾端。

但是有一个解决方案:transition在 JavaScript 中创建(不要将其放在样式表中的任何位置),将其删除(之后不会对 DOM 中的任何位置transition应用任何规则#upper),更改高度,然后重新添加它. 不完美,但也不是依赖于错误的黑客。

http://jsfiddle.net/grantheaslip/e3quW/

JavaScript

upper.style.removeProperty('transition');
upper.style.removeProperty('-o-transition');
upper.style.removeProperty('-moz-transition');
upper.style.removeProperty('-webkit-transition');
upper.style.removeProperty('height');
// force a reflow
// if (upper.offsetParent) { /* empty */ }
upper.style['transition'] = 'height 1000ms';
upper.style['-o-transition'] = 'height 1000ms';
upper.style['-moz-transition'] = 'height 1000ms';
upper.style['-webkit-transition'] = 'height 1000ms';

样式表

#upper {
    background-color: red;
}

WebKit(但不是 Gecko 或 Presto!)

任何仅因 1ms 超时而起作用的东西可能永远都不应该接近生产,但我认为这是值得指出的,以防它帮助某人解决这个问题。

我的猜测是 WebKit 与 Presto 或 Gecko 没有相同的问题,而是包含一个优化,它收集应用在同一函数中的样式更改并一次应用它们。同样,来自从未接近 WebKit 源代码或 CSS3 规范的人的纯粹猜测。

http://jsfiddle.net/grantheaslip/DFcg9/

JavaScript

window.setTimeout(function() {
    upper.style.removeProperty('transition-property');
    upper.style.removeProperty('-o-transition-property');
    upper.style.removeProperty('-moz-transition-property');
    upper.style.removeProperty('-webkit-transition-property');
    upper.style.removeProperty('opacity');
    lower.style.removeProperty('opacity');
}, 1);

Gecko、Presto 和 WebKit

这是两种解决方案的结合。同样,由于超时黑客,这真的不应该被使用。

http://jsfiddle.net/grantheaslip/N3NrB/

于 2011-06-27T17:26:40.897 回答