I have a question regarding transitions, now as I'm sure most are aware you can't transition from display:block to display:none because they are essentially binary options and are either on or off, and therefore there are no intermediate steps that can be animated.
That being the case why then can I transition visibility which like display:block, display:none is a binary options with no intermediate steps that can be animated.
Now I know that strictly speaking when you transition visibility you are not really transitioning visibility, what you are actually doing is combining visibility with something like opacity and then using the timing function to set a time delay on visibility, so that the visibility is flipped when the opacity fade is finished as opposed to right away which is the normal behaviour.
So something like this
transition-property: opacity;
transition-duration: 1s
transition-timing-function: linear;
transition-property: visibility;
transition-delay: 1s;
Now what I'm curious about is why when I specify a transition on display:block, display:none does it not work the same way as it does for visibility, in that I do an opacity fade over say 1 second and then flip the display from block to none after the 1 second fade has finished.
More over why do I even need to specify an opacity fade in the first place, because when transitioning both display:block, display:none and visibility:visible, visibility:hidden the default behaviour for both of these should be the same as if I set an opacity fade between the visible and invisible states.
Therefore in theory I shouldn’t actually need to set an opacity fade, because the default behaviour for transitioning both display:block, display:none and visibility:visible, visibility:hidden should insert an opacity fade between the visible and invisible states automatically, and then the states should simply be flipped at the start/end of the fade.
So when fading in
The visibility / display is flipped to either visible / block immediately, but opacity remains at 0 and then 10 milliseconds later the opacity fade starts to fade the element in over say 1 second or what ever duration is specified.
On fade out
The opacity fade runs fading the element out over say 1 second or what ever duration is specified, and then visibility / display is flipped to either hidden / none after the specified duration.
You can see the effect in this simple example just copy the code in to a new text document save it as a html file and then run it.
Code: Select all
<!DOCTYPE html>
<html lang="en-GB">
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style>
#tooltip_container
{
width: 150px;
background-color:pink;
}
#tooltip_container p
{
margin:0;
padding:3px 5px;
}
.tooltip
{
width: 100px;
color:black;
background-color: rgb(255, 255, 225);
border:1px solid black;
}
</style>
</head>
<body>
<div id="tooltip_container">
<p id="hover">Hover Me</p>
<div class="tooltip">
<p>hi im a tool tip</p>
</div>
</div>
<script>
var element = document.getElementById("tooltip_container").querySelector("div")
element.style.cssText = "display:none; opacity: 0;";
function hoveron(event)
{
element.style.cssText = "display:block;opacity: 0;";
setTimeout (fadein, 10);
}
function fadein()
{
element.style.cssText = "opacity: 1; transition: opacity 0.7s ease-in-out;";
}
function hoveroff(event)
{
element.style.cssText = "opacity: 0; transition: opacity 0.7s ease-in-out;";
setTimeout (fadeout, 700);
}
function fadeout()
{
element.style.cssText = "display:none;";
}
document.getElementById("hover").addEventListener("mouseover", hoveron);
document.getElementById("hover").addEventListener("mouseout", hoveroff);
</script>
</body>
</html>
When reversing the process you can see how again its possible to insert an opacity fade between display:block / display:none and then flip the display from none to block while still maintaining a smooth fade in animation, which is currently not possible with css alone since the transition time delay does not work with display:block, display:none the same way it does for visibility:visible, visibility:hidden and of course this same process will also work for other things like overflow which also do not currently work with transitions.
Now of course there are other ways to remove an element from the document flow such as using absolutely relative positioning aka the process where by you position something absolutely, within a relatively positioned parent, but I deliberately decided not to do that because it makes it difficult to see the effect.
Now while I'm sure this is a little crude and there are probably better ways to do this, given my limited knowledge of JavaScript ultimately this is how transitioning both display:block / display:none and visibility:visible, visibility:hidden should work by default and of course if something like this was the default implementation then the code would be optimised and would be much faster, simpler and much less bulky as all you would need to do to is specify
transition-property: display;
transition-duration: 1s
transition-timing-function: linear;
transition-delay: 1s;
and doing that would caused exactly the effect you see in my simple little example, a smooth fade in and out and and then at the start / end of the fade the viability/display would be flipped to either viable/hidden or block/none.