I'm having trouble creating a flyout menu with a specific effect. The flyout goes from display:none to block and then I use jquery to animate opacity from 0 to 1 (and vice versa). This is necessary because otherwise the transition does not happen when the element has just had it's display property changed. I did not think that this would propagate to children. But inside of my flyout I have 4 columns of links that have an opacity transition, each with it's own delay so they come in one at a time. However, this does not work as the flyout appears. They are instantly at opacity: 1 and even with a long delay time it still does not work.
Is there a way around this? I knew that CSS animation alongside a display change on the same element did not work, but finding out that any child animations also do not work is a little frustrating. I'd rather not have to write javascript when the CSS is so simple. But if javascript is the only answer, then that will be an easy solve.
Here's a very simplified example of the code:
$flyout.addClass('in').animate({opacity: 1}, 200, "linear");
"in" is the class that causes the transition on the columns:
.flyout { display: none; }
.flyout.in { display: block; }
.columns li {
opacity: 0;
-webkit-transition: opacity 0.2s;
}
.flyout.in .columns li { opacity: 1; }
// delay increases with each column
.columns > li:first-child {
-webkit-transition-delay: 0.2s;
}
When we want to use transition for display:none to display:block, transition properties do not work. The reason for this is, display:none property is used for removing block and display:block property is used for displaying block. A block cannot be partly displayed.
display is not one of the properties that transition works upon. See Animatable CSS properties for the list of CSS properties that can have transitions applied to them.
To work around this always allow the element to be display block but hide the element by adjusting any of these means: Set the height to 0. Set the opacity to 0. Position the element outside of the frame of another element that has overflow: hidden.
Is there a way around this? I knew that CSS animation alongside a display change on the same element did not work, but finding out that any child animations also do not work is a little frustrating.
It does not only apply to the same element, but the entire sub-tree - as the entire sub-tree is not rendered.
display: block
on the wrapper, then force a reflow (by flushing the style buffer with wrapperElement.offsetHeight;
), then add a class that sets opacity:1
to your children (or do whatever you're doing to kick off the animations).width: 0; height: 0; overflow: hidden; visibility: hidden;
(or, for nicer transitions transform: scale(0); visibility: hidden; pointer-events: none;
)As soon as display:none
is involved, you're screwed when it comes to transitions. The best way is to avoid it. I've been using the second option without any significant problems for quite a while now.
edit after OP added some demo code:
.animate()
of the wrapper can be done in CSS as well-webkit-transition
, but the proper transition
as well// delay increases with each column
looks like a misconception. all elements the selector .columns > li:first-child
applies to will have the exact same delay - they won't wait for the previous element to finish its transition. If you want to define that in CSS, you'll have to play with :nth-child() or one of its cousinsif you want only to change the opacity
you can use FadeIn and FadeOut functions of JQuery but if you want more complex transition you can use CSS3 (this is a realy good library).
See this DEMO where you can see this two different way.
You can also add a controll to the class like this:
$("OBJECT").click(function(){
if ($("OBJECT").hasClass("CLASS")){
$("OBJECT").removeClass("CLASS");
} else {
$("OBJECT").addClass("CLASS");
}
});
to make two way functions.
$(document).ready(function(){
$("#fadeOut").click(function(){
var duration = 500;
$("#div").fadeOut(duration);
});
$("#css").click(function(){
$("#div").addClass("out");
setTimeout(
function() {
$("#div").css("display", "none");
},
2001);
});
});
#div {
width:200px;
height:200px;
background-color:red;
text-align:center;
vertical-align:middle;
/* Animation CSS */
-webkit-animation-duration: 2s;
animation-duration: 2s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
}
/* Setup CSS3 animations */
@-webkit-keyframes out {
0% {
-webkit-transform-origin: top left;
transform-origin: top left;
-webkit-animation-timing-function: ease-in-out;
animation-timing-function: ease-in-out;
}
20%, 60% {
-webkit-transform: rotate3d(0, 0, 1, 80deg);
transform: rotate3d(0, 0, 1, 80deg);
-webkit-transform-origin: top left;
transform-origin: top left;
-webkit-animation-timing-function: ease-in-out;
animation-timing-function: ease-in-out;
}
40%, 80% {
-webkit-transform: rotate3d(0, 0, 1, 60deg);
transform: rotate3d(0, 0, 1, 60deg);
-webkit-transform-origin: top left;
transform-origin: top left;
-webkit-animation-timing-function: ease-in-out;
animation-timing-function: ease-in-out;
opacity: 1;
}
to {
-webkit-transform: translate3d(0, 700px, 0);
transform: translate3d(0, 700px, 0);
opacity: 0;
}
}
@keyframes out {
0% {
-webkit-transform-origin: top left;
transform-origin: top left;
-webkit-animation-timing-function: ease-in-out;
animation-timing-function: ease-in-out;
}
20%, 60% {
-webkit-transform: rotate3d(0, 0, 1, 80deg);
transform: rotate3d(0, 0, 1, 80deg);
-webkit-transform-origin: top left;
transform-origin: top left;
-webkit-animation-timing-function: ease-in-out;
animation-timing-function: ease-in-out;
}
40%, 80% {
-webkit-transform: rotate3d(0, 0, 1, 60deg);
transform: rotate3d(0, 0, 1, 60deg);
-webkit-transform-origin: top left;
transform-origin: top left;
-webkit-animation-timing-function: ease-in-out;
animation-timing-function: ease-in-out;
opacity: 1;
}
to {
-webkit-transform: translate3d(0, 700px, 0);
transform: translate3d(0, 700px, 0);
opacity: 0;
}
}
.out {
-webkit-animation-name: out;
animation-name: out;
}
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script type="text/javascript" src="script.js"></script>
</head>
<body>
<div id="div"></div>
<button id="fadeOut">fadeOut</button>
<button id="css">CSS3</button>
</body>
</html>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With