我想在已设置display: none
的元素上进行css转换。请考虑以下代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Transition From Hidden</title>
<style type="text/css">
div {
-webkit-transition-property: all;
-webkit-transition-duration: 2s;
}
div.hidden {
display: none;
opacity: 0;
}
div.from {
opacity: 0;
}
</style>
<script type="text/javascript">
function loaded() {
var e = document.getElementById("foo");
e.className = "from";
window.webkitRequestAnimationFrame(function(t) {
e.className = null;
});
}
</script>
</head>
<body onload="loaded()">
<div id="foo" class="hidden">
My test div
</div>
</body>
</html>
我想从class="div.hidden"
转到class=""
,即从display: none; opacity: 0;
转到display: block; opacity: 1;
但是,在chrome(至少)中有一个display: none
的对象没有动画。元素立即进入结束状态。
我的解决方法是首先将元素设置为display: block; opacity: 0;
,然后在下一帧中进行转换(使用requestAnimationFrame()
。这有点尴尬,我无法做到在spec中找到有关此行为的任何解释。我知道我可以使用visibility
- 属性,但我不想使用它,因为我不想要布局隐藏的元素。
所以,问题是:这是正确的行为还是错误?如果它是正确的行为,是否有更好的方法来编写代码?请注意,我不知道是否有任何库可以执行此操作,我想知道是否有更好的方法直接在DOM上执行此操作。
答案 0 :(得分:7)
关于这是否在规范中的问题,www-style@w3.org列表here上有一个有趣的帖子。我没有读过所有内容,但似乎他们没有从none
开始制作动画,并且过渡规范也需要澄清这一点。
更新:我已经询问了邮件列表,并且我得到了这个工作组会议minutes的链接,如果开始状态是,则决定不应该转换display: none
。
要确保执行转换,必须确保在设置为新目标之前计算动画属性的值。当display设置为none时,通常不会计算值。这是一个有效的例子:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Fade</title>
<style>
.hidden { display: none }
.start { opacity: 0 }
.transition { opacity: 1; -webkit-transition: opacity 1s }
</style>
</head>
<body>
<div id='div' class="hidden">Test</div>
<script>
var elem = document.getElementById('div');
function ontransitionend(event) {
elem.className = null;
elem.removeEventListener('transitionend', ontransitionend);
}
elem.addEventListener('transitionend', ontransitionend);
elem.className = 'start';
window.getComputedStyle(elem).opacity;
elem.className = 'transition';
</script>
</body>
</html>
请注意,您必须访问opacity属性。仅仅致电getComputedStyle()
!
答案 1 :(得分:2)
您不一定要转发transitionend
回调。
要在不透明度属性(或其他)上显示最初具有display:none
的隐藏元素,只需使用内联样式设置display:block
,然后删除CSS类.hidden
以设置元素的动画如你所愿:
CSS:
#foo {
display: none;
opacity: 1;
/*optional, other ending properties...*/
transition: opacity 1s;
}
.hidden {
opacity: 0;
/*optional, other starting properties...*/
}
HTML:
<div id="foo" class="hidden">
My test div
</div>
最后,javascript部分显示带有转换的元素:
var elem = document.getElementById('foo');
elem.style.display = 'block';
elem.classList.remove('hidden');
答案 2 :(得分:1)
有几个css属性无法以小步长递增(display
none
和block
之间25%的fadeIn
值是多少?),尤其是那些非数字值。您描述的解决方法几乎是处理此问题的标准方法。例如,jQuery在其fadeOut
和height
方法中使用类似的东西。
如果您想要设置从不占空间到标准布局的过渡动画,您可以转换width
和{{1}}属性。
答案 3 :(得分:1)
显示:没有意味着你可以到达元素,但首先你应该确保 元素已被渲染。 您可以在jquery中使用ready函数或在javascript中实现它以确保元素存在。 你可以通过使用:javascript(使用计时器增加不透明度)或jquery如下
来完成上述操作<html>
<head>
<meta charset="utf-8">
<title>CSS Transition From Hidden</title>
<script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
<script src="Scripts/jquery-1.4.1.js" type="text/javascript"></script>
<style type="text/css">
div.hidden {
display: none;
opacity: 0;
}
</style>
<script type="text/javascript">
$.ready = function () {
$("#foo").fadeIn(2000);
}
</script>
</head>
<body>
<div id="foo" class="hidden">
My test div
</div>
</body>
</html>
答案 4 :(得分:1)
我有同样的问题,我不认为它应被视为浏览器可接受的行为。问题不是任何人都试图动画实际的显示属性。它不能有一个带display:none的元素,将属性更新为内联或其他,然后为不透明度设置动画,例如,即使你在显示更新后放置超时10秒也不行。
我现在的解决方法是将宽度和高度设置为0,溢出到隐藏,更新这些值,然后更新动画属性。至少它的行为更类似于display none而不是隐藏的可见性。
答案 5 :(得分:0)
display:none插入动画。这是一个耻辱,我认为应该由浏览器解决。我之前通过将z-index设置为-1(隐藏元素)来解决问题,如果绝对定位也将其从静态布局中删除。你实际上可以转换z-index(虽然它看起来不像动画),因此不会弄乱不透明度动画。
这对我的应用程序很有用,虽然我最终不得不使用JavaScript继续将display属性设置为none到block,因为我最终需要在overflow:auto元素中使用fading元素,当它不是时隐藏,在不希望的时间创建滚动条。