为什么在隐藏元素时设置属性后显示元素时会发生转换?

时间:2011-06-27 00:46:05

标签: css css3 css-transitions reflow

可以看到一个实例:here

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

再次点击方块之前,请检查toggle功能。看看JavaScript,我希望红色方块的高度可以重置为原始值而不会触发转换。应该抑制转换,因为转换属性在高度更改时暂时设置为none

现在再次点击广场。两个彩色方块都立即完全不透明,但红色方块随着其高度从0过渡到原始值而向下滑动。就好像内联样式设置的高度没有被toggle函数删除,直到元素可见,然后转换属性也被重置。

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

1 个答案:

答案 0 :(得分:4)

这确实是一个奇怪的问题。我不认为你的代码中有任何错误 - 当前的浏览器实现只是错误。

我在使用CSS转换之前遇到了这些看似明显的错误,并且在不诉诸拜占庭黑客的情况下处理它们是一件非常痛苦的事情,一旦他们正在解决的错误被修复肯定会破坏(在这种情况下,我的WebKit修复)。

我真的很喜欢这个,但是无法想出一个干净的解决方案,它可以在三个主要的转换支持布局引擎(WebKit,Gecko和Presto)中工作。也就是说,这就是我所想到的 - 希望有人比我更聪明(或者只是以新鲜的眼光看待它)可以接受这个答案并将其转化为真正的解决方案。

Gecko和Presto(但不是WebKit!)

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

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

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

的JavaScript

#upper

样式表

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';

WebKit(但不是Gecko或Presto!)

任何仅因1ms超时而起作用的东西可能永远不会接近生产,但我认为这值得指出,以防它有助于解决这个问题的根源。

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

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

的JavaScript

#upper {
    background-color: red;
}

Gecko,Presto和WebKit

这两种解决方案相结合。再次,由于超时黑客,这真的不应该使用。

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