0

I've got a simple toggle plus sign that should trigger a div to appear and rotate into an X which can then be clicked to close the div.

Everything works as planned except there is no smooth transition in the rotation of the plus, it just appears already rotated.

If I remove the display:none from the #showbox div and remove $("#showbox").show(), the animation/transition works. It's only if the div is hidden and then shown with .show() that it just rotates without animating.

I'm sure I can think of a workaround, I'm just wondering if anyone can explain why this might be happening

$("#togglebox").click(function() {
  $("#showbox").show();
  $("#showbox .toggleplus").toggleClass("togglex");
});
#showbox {
  background: #000;
  width: 500px;
  height: 200px;
  display: none;
}

.toggleplus {
  width: 30px;
  height: 30px;
  transition: all .5s;
  color:#111;
}

#showbox .toggleplus {
color:#FFF;
}

.togglex {
  transform: rotate(-46deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="togglebox">
  <p>LEARN MORE</p>
  <div class="toggleplus">+</div>
</div>

<div id="showbox">
  <div class="toggleplus">+</div>
  <p>Blah Blah Blah</p>
</div>

4
  • 1
    Where is the plus sign in this code? Commented Jul 21, 2017 at 20:56
  • Wasn't really necessary to add all the html for the question, but I threw a simple + in there for clarification. Commented Jul 21, 2017 at 20:59
  • As you can see the first time the snippet is run and the + is clicked, it will not animate. On subsequent clicks it will. Commented Jul 21, 2017 at 21:01
  • Well, if we can't see the thing that is supposed to transition, it's hard to know what your issue is. I have added the same + sign in my answer below. Commented Jul 21, 2017 at 21:02

1 Answer 1

1

The issue is that the UI updates in a different thread than the JavaScript executes in and that UI thread executes faster than the JS.

You can fix this by adding a short delay, which forces the UI not to update until the function is complete.

$("#togglebox").click(function(){
        $("#showbox").show();
        setTimeout(function(){
          $("#showbox .toggleplus").toggleClass("togglex");
        },20);
    });
#showbox {
    	background:#fff;
    	width:500px;
      height:200px;
    	display:none;
    }
    
    .toggleplus {
    	float:right;
    	width:30px;
    	height:30px;
    	transition:all .5s;
    }
    
    .togglex {
    	transform: rotate(-46deg);
    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


    <div id="togglebox">
        <p>LEARN MORE</p>
        <div class="toggleplus"></div>
    </div>
    	
    <div id="showbox">
        <div class="toggleplus">+</div>
        <p>Blah Blah Blah</p>
    </div>

Another way to accomplish this with JQuery is to have the addition of the rotation class code added as a callback to the show() method:

$("#togglebox").click(function(){
        // Passing a function to the show method sets it up as a callback to
        // be executed after the show() animation is complete.
        $("#showbox").show(function(){
          $("#showbox .toggleplus").toggleClass("togglex");
        });
    });
#showbox {
    	background:#fff;
    	width:500px;
      height:200px;
    	display:none;
    }
    
    .toggleplus {
    	float:right;
    	width:30px;
    	height:30px;
    	transition:all .5s;
    }
    
    .togglex {
    	transform: rotate(-46deg);
    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


    <div id="togglebox">
        <p>LEARN MORE</p>
        <div class="toggleplus"></div>
    </div>
    	
    <div id="showbox">
        <div class="toggleplus">+</div>
        <p>Blah Blah Blah</p>
    </div>

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, I figured setTimeout() was the solution, thanks for the explanation as to why.
Nice, I didn't realize show() also had a callback.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.