mouseover issue with animation duration

Solution 1:

Simple as that, use mouseenter instead of mouseover jsFiddle

Difference between mouseenter and mouseover

the reason is that mouseover is prone to event bubbling from child elements (triggering again the mouseover event). Since every child element triggered a new mouseover (with an expand animation which was not queue-cleared) resulted in: expand 400ms * times every child triggered a mouseover = an extended animation time the #reference should stay expanded.

Example showing the difference between mouseover and mouseenter events:

var mouseover = 0, mouseout = 0, mouseenter = 0, mouseleave = 0;
$("#parent").on("mouseover mouseout mouseenter mouseleave", function(e) {
  $("#"+e.type).text(++window[e.type]);
});
*{margin:0;}
#parent{
  padding: 12px;
  background: #0cf;
  display: inline-block;
  margin-right:40px;
}
.child{
  width:50px;
  height:50px;
  background: #f0c;
  margin: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Mouseover <b id=mouseover>0</b> Mouseout <b id=mouseout>0</b></p>
<p>Mouseenter <b id=mouseenter>0</b> Mouseleave <b id=mouseleave>0</b></p>
<div id="parent">
  <div class="child"></div>
  <div class="child"></div>
</div>

Use those events always is this pair/combinations

mouseenter / mouseleave
mouseover / mouseout // there's really rare occasions where you want to use this two guys

But most importantly don't forget that some users are fast with their mouse,
multiple hovers might end building up your animations, so you need to clear your animations queue (buildups) using .stop()

$("#reference").on('mouseenter mouseleave', function(evt) {
  $(this).stop().animate({
    left: evt.type === 'mouseenter' ? 0 : -115
  });
});

Updated jsFiddle

The good news is you don't need JS at all

simply add this to your CSS:

#reference {
  /* other styles... */
  left: -115px;
  transition: 0.4s;
  -webkit-transition: 0.4s;
}
#reference:hover{
  left: 0;
}

CSS-only jsFiddle