Log in

View Full Version : height/width transition not working after hiding div



gib65
01-21-2016, 04:34 PM
Hello,

I'm experimenting with CSS transitions. If you go to the follow site:

http://www.mm-theory.com/shahspace/widthTransition/widthTransition.html

you'll see what I've got so far.

What I've got is two div. On the left, you have a green div of which you can control the width with the buttons. On the right, you have a red div of which you can control the height with the buttons.

As you can see, growing and shrinking the divs works with CSS transitions.

The only thing which doesn't work (and this is what I need help with) is getting the transition to work when you go from hidden to a different size. So if you click the "hide" button, the div shrinks to nothing and disappears. But then if you click "small" it just reappears at the appropriate size (no transition).

I trust that you can get at the code at the site, but if not, let me know and I'll post it.

One thing that occurred to me was that maybe when you hide a div (using the jquery .hide() function), it sets the width/height to auto. In that case, calling .show() and then adding a class with a non-zero width/height may not result in a transition because how do you transition from auto to 100px (for example)?

To test that, I created this alternate version:

http://www.mm-theory.com/shahspace/widthTransition2/widthTransition.html

In the javascript, instead of doing this:

$("#RightDiv").show();
$("#RightDiv").removeClass("bigHeightClass").removeClass("hiddenHeightClass");
$("#RightDiv").addClass("smallHeightClass");

I did this:

if ($("#RightDiv").css("display") == "none")
{
$("#RightDiv").show();
$("#RightDiv").height(0);
}

$("#RightDiv").removeClass("bigHeightClass").removeClass("hiddenHeightClass");
$("#RightDiv").addClass("smallHeightClass");

I was hoping that by setting the width to 0 right after calling .show() and then adding the appropriate class, the transition would occur. But it didn't work. In fact, it's even worse. Clicking "small" or "big" after hiding it only makes it visible but doesn't grow the width/height beyond 0.

Beverleyh
01-21-2016, 06:57 PM
I can't check on iPad but I believe that using .hide() in jQuery applies an inline style of display:none; - here's your problem - you can't transition the display property.

Maybe try a different approach; Don't use .hide() - transition opacity instead.

gib65
01-21-2016, 07:51 PM
If you can't visit the site, then here's the full code:



<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Transition</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />

<link href="CSS\jquery-ui.css" rel="stylesheet" />
<link href="CSS\jquery-ui.structure.css" rel="stylesheet" />
<link href="CSS\jquery-ui.theme.css" rel="stylesheet" />

<script src="Script\jquery-1.11.1.min.js"></script>

<script src="Script\jquery-ui.min.js"></script>

<style>

.transitionWidthClass{
-webkit-transition: width 1s ease-in;
-moz-transition: width 1s ease-in;
-o-transition: width 1s ease-in;
transition: width 1s ease-in;

}

.smallWidthClass{
display: inline-block;
width: 100px;
}

.bigWidthClass
{
display: inline-block;
width: 200px;
}

.hiddenWidthClass
{
display: inline-block;
width: 0px;
}

.transitionHeightClass{
-webkit-transition: height 1s ease-in;
-moz-transition: height 1s ease-in;
-o-transition: height 1s ease-in;
transition: height 1s ease-in;

}

.smallHeightClass{
display: inline-block;
height: 100px;
}

.bigHeightClass
{
display: inline-block;
height: 200px;
}

.hiddenHeightClass
{
display: inline-block;
height: 0px;
}
</style>

</head>

<body style="text-align: center;">

<table style="width: 100%; height: 100vh;" border="1">
<tr>
<td style="width: 50%;">
<div id="LeftDiv" class="transitionWidthClass smallWidthClass" style="display: inline-block; background-color: green; height: 200px; border: 3px blue solid; border-radius: 4px;">
</div>


<br/>
<br/>
<br/>


<input type="button" value="Hide" onclick="LeftHideButton_Click();"/>
<br/>
<input type="button" value="Small" onclick="LeftSmallButton_Click();"/>
<br/>
<input type="button" value="Big" onclick="LeftBigButton_Click();"/>
</td>
<td style="width: 50%;">
<div id="RightDiv" class="transitionHeightClass smallHeightClass" style="display: inline-block; background-color: red; width: 200px; border: 3px blue solid; border-radius: 4px;">
</div>


<br/>
<br/>
<br/>


<input type="button" value="Hide" onclick="RightHideButton_Click();"/>
<br/>
<input type="button" value="Small" onclick="RightSmallButton_Click();"/>
<br/>
<input type="button" value="Big" onclick="RightBigButton_Click();"/>
</td>
</tr>
</table>

<script>
$(document).ready(function() {

$(window).on("webkitTransitionEnd", function(event)
{
$(".hiddenWidthClass").hide();
$(".hiddenHeightClass").hide();
});

});

var LeftHideButton_Click = function()
{
$("#LeftDiv").removeClass("smallWidthClass").removeClass("bigWidthClass");
$("#LeftDiv").addClass("hiddenWidthClass");
};

var LeftSmallButton_Click = function()
{
$("#LeftDiv").show();
$("#LeftDiv").removeClass("bigWidthClass").removeClass("hiddenWidthClass");
$("#LeftDiv").addClass("smallWidthClass");
};

var LeftBigButton_Click = function()
{
$("#LeftDiv").show();
$("#LeftDiv").removeClass("smallWidthClass").removeClass("hiddenWidthClass");
$("#LeftDiv").addClass("bigWidthClass");
};

var RightHideButton_Click = function()
{
$("#RightDiv").removeClass("smallHeightClass").removeClass("bigHeightClass");
$("#RightDiv").addClass("hiddenHeightClass");
};

var RightSmallButton_Click = function()
{
$("#RightDiv").show();
$("#RightDiv").removeClass("bigHeightClass").removeClass("hiddenHeightClass");
$("#RightDiv").addClass("smallHeightClass");
};

var RightBigButton_Click = function()
{
$("#RightDiv").show();
$("#RightDiv").removeClass("smallHeightClass").removeClass("hiddenHeightClass");
$("#RightDiv").addClass("bigHeightClass");
};
</script>
</body>
</html>


I have some jquery references in there, so if you want to try this yourself, you'll have to provide those yourself.

In any case, here's a couple example functions. First the hide fuction:

var RightHideButton_Click = function()
{
$("#RightDiv").removeClass("smallHeightClass").removeClass("bigHeightClass"); // <-- remove the small and big classes
$("#RightDiv").addClass("hiddenHeightClass"); // <-- add the hide class (just sets the height to 0)
};

So this function gets called when you click the hide button. It transitions from height: 100px (if it has the smallHeightClass) or 200px (if it has the bigHeightClass) to height: 0 (by being given the hiddenHeightClass). It then hides the div (Calling .Hide()) in the webkitTransitionEnd event handler.

This works pretty smoothly.

Note that it's the height/width that I'm trying to transition, not the opacity (although setting opacity to 0 in the webkitTransitionEnd event handler instead of calling .hide() might work).

After it's been hidden, I want to do the reverse process: I want to show it, then transition to the "small" or "big" size (which ever button gets clicked).

Here's an example:

var RightBigButton_Click = function()
{
$("#RightDiv").show(); // <-- Make the div visible again
$("#RightDiv").removeClass("smallHeightClass").removeClass("hiddenHeightClass"); // <-- remove the small and hidden classes
$("#RightDiv").addClass("bigHeightClass"); // <-- Add the big class
};

This is what's not working. You would think, according to the sequence of steps above, that the div would first become visible (just a flat line) and then expand to height: 200px. But this is not what happens. It becomes visible already at height: 200px. It skips the transition.

Beverleyh
01-21-2016, 08:08 PM
No I meant that I couldn't check the inline style applied by .hide() in the developer toolbar. I'm pretty sure that im right though so please see my previous comment re: not being able to transition the display property.

molendijk
01-21-2016, 10:00 PM
The problem might reside elsewhere, since the code works fine with Firefox and IE except for the borders which don't hide. But then again that might explain the different behaviour in FF and IE, since hiding is not complete there.

gib65
01-21-2016, 11:29 PM
I figured it out.

Apparently, the .show() function has a delay. So in this function:

var LeftSmallButton_Click = function()
{
$("#LeftDiv").show();
$("#LeftDiv").removeClass("bigWidthClass").removeClass("hiddenWidthClass");
$("#LeftDiv").addClass("smallWidthClass");
};

when .show() is called, it doesn't actually show the div until after 400 milliseconds. By then, the bigWidthClass and hiddenWidthClass have been removed and the smallWidthClass added. Since the div is hidden all that time, no transition occurs, and by the time the 400 milliseconds is over, the deal is done.

To fix it, I added a 0 to .show() to indicate 0 milliseconds. The function now looks like this:

var LeftSmallButton_Click = function()
{
$("#LeftDiv").show(0);
$("#LeftDiv").removeClass("bigWidthClass").removeClass("hiddenWidthClass");
$("#LeftDiv").addClass("smallWidthClass");
};

Now it works: http://www.mm-theory.com/shahspace/widthTransition/widthTransition.html

molendijk
01-21-2016, 11:38 PM
Nice!
But I would remove the borders (3px blue solid) as they are still visible in FF and IE after a click on the hide button.