0

I have a strange behavior with css transitions. I want to hide/show an image with a transition effect. I set up html:

<div class="up">
     <div class="wrapper_hiden wrapper_see">
       <img src="">
     </div>
    ...
   </div>
   <div class="down">
   </div>

and css:

.wrapper_hiden{
  height: 0;
  float: left;
  margin: 0;
  opacity: 0;
  transition: all 1s;
  overflow: hidden;
}
.wrapper_see{
  height: 100px;
  margin: 5px;
  opacity: 1;
}
.wrapper_hiden img{
  height: 100%;
}

Now if I use JQuery to toggle wrapper_see class I can show/hide image with effect. Here is fiddle with a button to do that.

Problem start when I want to hide element and after hidden prepend it to another div and show. Basically I want to move image from div to div but with transition effects.

$('body').on('click', '.up .wrapper_hiden',function(){
    var $wrapper_hide = $(this);
    $wrapper_hide.removeClass('wrapper_see');
    $wrapper_hide.one('transitionend', function(e) {
            $(this).prependTo('.down').addClass('wrapper_see');
    });
  });

However transition efect is not reacting after prepentTo.

Have spent hours but can not understand why it works with first approach but dont with second.

3
  • Just to clarify, are you asking why the images appended / removed from the red background section don't have any transitions applied? Commented Feb 9, 2017 at 21:49
  • I click an image in yellow block. It disappears with a transition effect. I expect it to appear in red block with transition effect. But there is no transition effect then. Why? I use the same techique as when clicking button test. Commented Feb 9, 2017 at 21:56
  • Use animate.css Commented Feb 9, 2017 at 21:59

2 Answers 2

3

Because you're not adding the correct sequences of classes to properly execute the transition. What you want is the height to initially be 0, and opacity be zero, THEN you want to set the height, and set your opacity so the transition takes place.

I forked your fiddle and solved the problem. Let me know if you don't understand what I did, or if you have any other problems.

** You need to do the same with your button handler. Right now the code is buggy.

$(document).ready(function(){
	$('body').on('click', 'button',function(){
  	$('.la').toggleClass('wrapper_see');
 });
	$('body').on('click', '.up .wrapper_hiden',function(){
  	var $wrapper_hide = $(this);
   	$wrapper_hide.removeClass('wrapper_see');
    $wrapper_hide.one('transitionend', function(e) {
			$(this).prependTo('.down').addClass('wrapper_hiden');
      setTimeout(function(){$wrapper_hide.addClass('wrapper_see')}, 0);
    });
  });
  $('body').on('click', '.down .wrapper_hiden',function(){
  	var $wrapper_hide = $(this);
   	$wrapper_hide.removeClass('wrapper_see');
    $wrapper_hide.one('transitionend', function(e) {
			$wrapper_hide.prependTo('.up').addClass('wrapper_hiden');
      setTimeout(function(){$wrapper_hide.addClass('wrapper_see')}, 0);
    });
  });
});
.up{
  position: relative;
  background: yellow;
  height: 120px;
}
.down{
  background: red;
  height: 120px;
}
.wrapper_hiden{
  height: 0;
  float: left;
  margin: 0;
  opacity: 0;
  transition: all 1s;
  overflow: hidden;
}
.wrapper_see{
  height: 100px;
  margin: 5px;
  opacity: 1;
}
.wrapper_hiden img{
  height: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>press</button>
<div class="up">
  <div class="wrapper_hiden wrapper_see">
    <img src="http://www.w3schools.com/css/img_fjords.jpg">
  </div>
  <div class="wrapper_hiden la">
    <img src="http://www.jqueryscript.net/images/Simplest-Responsive-jQuery-Image-Lightbox-Plugin-simple-lightbox.jpg">
  </div>
  <div class="wrapper_hiden wrapper_see">
    <img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTOLu1xsB5p3fYIGSG06rWNOXau_UJRm5Kx7EqDKibwolZq9U_g">
  </div>
  <div class="wrapper_hiden wrapper_see">
    <img src="https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcS7OateqmmWaL3DvIB83FktVJ2JL6cDOYRoxTol45tAi_9ee4av">
  </div>
</div>
<div class="down">
</div>

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

2 Comments

Ok ,that does the trick, but not entirely sure how it works. Why do you add class wrapper_hiden? Isn't it already there? And why you use setTimeout 0 seconds? Whats the point of that?
@KārlisJanisels Hi, sorry for the late reply. Basically you want to think of css transitions as properties changing sequentially. When you add two classes at the same time, css transitions can't take place, because then the element will just take the css properties of whatever has the higher priority. I wanted height to start at 0 and opacity at 0, then after a tiny period of time, I wanted to change height to x and opacity to 1. This is why I used setTimeout, to create this sequential introduction. I hope this helps!
0

For jQuery you remove and add your class wrapper_see in one step, so the removement doesn't really happen. I solved this solution by delaying for one ms.

        $('body').on('click', '.up .wrapper_hiden', function () {
            var $wrapper_hide = $(this);
            $wrapper_hide.removeClass('wrapper_see').delay(1).queue(function (next) {
                $wrapper_hide.one('transitionend', function (e) {
                    $(this).prependTo('.down').addClass('wrapper_see');
                });
                next();
            });
        });

Comments

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.