22

I'm trying to do a transition from the center to left and reduce the height of an image. The height transition is working fine, but the margin just teleports to the left instead of animating.

this is my code:

#logo_img {
    height: 55px;
    width: 55px;
    background-color: red;
    margin-left: auto;
    margin-right: auto;
    display: block;
    transition: all 1s ease-in-out;
}

#logo_img.tiny {
    height:45px;
    margin-left: 0;
}

JS:

$('#logo_img').addClass('tiny');

working example: http://jsfiddle.net/v0w6s3ms/1/

any help?

DarkW
  • 575
  • 1
  • 6
  • 18

5 Answers5

29

You can't animate auto property instead try something like this

$(function() {
  setTimeout(function() {
    $('#logo_img').addClass('tiny');
  }, 1000);
});
#logo_img {
  height: 55px;
  width: 55px;
  background-color: red;
  margin-left: calc(50% - 55px);
  margin-right: auto;
  display: block;
  transition: all 1s ease-in-out;
}
#logo_img.tiny {
  height: 45px;
  margin-left: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section id="logo_img"></section>
Akshay
  • 14,138
  • 5
  • 46
  • 70
6

You want to transition from "margin-left:auto" to "margin-left:0". Auto is not a defined value, thats why it can't be decreased to zero. Set margin-left: 50% instead "auto".

Pvb
  • 446
  • 2
  • 5
3

Try this:

#logo_img {
    height: 55px;
    width: 55px;
    background-color: red;
    margin-left: 50%;  //Change the auto to 50%
    margin-right: auto;
    display: block;
    transition: all 1s ease-in-out;
}

#logo_img.tiny {
    height:45px;
    margin-left: 0;
}

JSFIDDLE DEMO

Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
1

in 2019 you can

/* replace */
margin-left: auto; 
/* with */
margin-left: calc(100% - 55px);

details:

It is also possible to make it with CSS now. use the property Calc and subtract the width of your element. Thus, the margin will be set specifically and not auto.

jQuery(document).ready(function( $ ) {
  $('#logo_img').on('click', function() {
  $(this).toggleClass('tiny');
  }, );
}); //end ready
#logo_img {
        height: 55px;
        width: 55px;
        background-color: red;
        margin-left: Calc(100% - 55px); 
        margin-right: auto;
        display: block;
        transition: all 1s ease-in-out;
    }
#logo_img.tiny {
    height:45px;
    margin-left: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<img id="logo_img" src="https://picsum.photos/100/200" alt="">
Herman
  • 43
  • 8
0

For someone whose content has an unfixed size:

This can also be achieved by using animation between state flex: none; and flex: auto;. But you will need to have a wrapper around the content, and the animation is applied to the wrapper, instead of the "auto" margins.

$('.content').click(function(e) {
  $(e.target).closest('.wrapper').toggleClass('move');
});
.container {
  display: flex;
  padding: 1rem;
  margin-bottom: 1rem;
  background: #D8E0BB;
  position: relative;
}

.wrapper {
  flex: none;
  transition: flex 1s ease;
  display: flex;
  position: relative;
  background: #B6CEC7;
}

.wrapper.move {
  flex: auto;
}

.wrapper.content-align-left {
  margin-left: auto;
}

.wrapper.content-align-ends {
  margin: auto;
}

.content {
  padding: 1rem;
  text-align: center;
  background: #86A3C3;
  color: #6B3074;
}

.content-align-right .content {
  margin-left: auto;
}

.content-align-left .content {
  margin-right: auto;
}

.content-align-center .content {
  margin: auto;
}

.content-align-ends .content:first-child {
  margin-right: auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div>
  Look for <b>"key property"</b> comment in the css for the important style to make the animation to work.
  <br><br>
</div>

<div class="container">
  <div class="wrapper content-align-right">
    <div class="content">
      Click Me <br> align right <br> ---------------------
    </div>
  </div>
</div>

<div class="container">
  <div class="wrapper content-align-left">
    <div class="content">
      Click Me <br> align left <br> ------
    </div>
  </div>
</div>

<div class="container">
  <div class="wrapper content-align-center">
    <div class="content">
      Click Me <br> align center <br> ---------------
    </div>
  </div>
</div>

<div class="container">
  <div class="wrapper content-align-ends">
    <div class="content">
      Click Me <br> align ends <br> ----------------------
    </div>
    <div class="content">
      Click Me <br> align ends <br> ------
    </div>
  </div>
</div>

Other possibilities:

  • Without wrapper: Toggle between transform: translate(50%, 0); margin-right: 100%; and transform: translate(50%, 0); margin-right: 50%;, but it will get complicated if you have 2 or more flexible sized element to animate.

  • With wrapper: Toggle between min-width: 0; and min-width: 100%;, but the animation may not look as smooth because the start/end phase of the animation may be cut because the element itself has a width.

EthanX
  • 185
  • 1
  • 9