这里可以看到一个实际的例子。
红色方块(显示)直接位于绿色方块(隐藏为溢出)的上方。点击方块,两个彩色方块都会立即变得完全透明。此外,红色正方形的高度设置为0;这会触发一个过渡,但过渡是看不见的,因为红色方块现在是透明的。
再次单击方形之前,请检查toggle
函数。看看JavaScript,我希望红色方块的高度可以重置为其原始值,而不会触发转换。应抑制转换,因为在更改高度时,转换属性会临时设置为none
。
现在再次点击方块。两个彩色方块都会立即变为完全不透明,但红色方块会随着高度从0过渡到原始值而向下滑动。就好像在元素可见之前,toggle
函数并没有删除内联样式设置的高度,而此时transition属性也已重置。
触发回流似乎会迫使应用高度的变化。(取消注释包含offsetParent
的行以进行测试。)这种行为发生在浏览器之间(至少是Chrome和Safari、Firefox和Opera),所以我想知道它是否不是某些规范的一部分。我检查过CSS转换模块,但没有成功。有什么想法吗?为什么会发生这种行为,为什么它在实现中如此一致?
这确实是一个奇怪的问题。我不认为您在代码中做了任何错误的事情——当前的浏览器实现只是有缺陷。
我以前在CSS转换中遇到过这种看似明显的错误,如果不使用拜占庭式的黑客攻击来处理它们,那将是一件非常痛苦的事情,一旦他们正在处理的错误得到修复(在这种情况下,是我的WebKit修复),这些黑客攻击肯定会崩溃。
我真的深入研究了这一点,但无法找到一个在支持布局引擎的三个主要转换(WebKit、Gecko和Presto)中有效的干净解决方案。也就是说,这就是我所想的——希望比我更聪明的人(或者只是用全新的眼光来看待这个问题)能够接受这个答案,并将其转化为真正的解决方案。
Gecko和Presto(但不是WebKit!)
看起来(我不是浏览器工程师或熟悉规范)transition-property
的任何当前或以前的值都将继续渲染,无论是否需要。因此,即使您更改了transition-property
的值,浏览器仍在后台渲染高度转换,当您将高度更改回时,你得到了它的尾端。
不过,有一个解决方案:用JavaScript创建transition
(不要把它放在样式表中的任何位置),删除它(之后DOM中的任何地方都没有transition
规则应用于#upper
),更改高度,然后重新添加它。这并不完美,但也不是一个依赖bug的破解。
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!)
任何只因1毫秒超时而起作用的东西可能永远不应该接近生产,但我认为这一点值得指出,以防有人发现这个问题。
我的猜测是,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);
壁虎、Presto和WebKit
这是两种解决方案的结合。同样,由于超时破解,这真的不应该使用。
http://jsfiddle.net/grantheaslip/N3NrB/