slideDown jumps abruptly at the end

I’ve built a fairly normal menu-submenu arrangement in a vertical column — nested ULs, using slideToggle to expand and collapse submenus.

The problem I’m trying to solve is in the way the submenus “jump” open at the very end. (I’m testing in the latest release of Chrome.) It’s probably most noticeable in the second submenu, “Benefits”. It doesn’t jump when menus are collapsing, only when they’re expanding.

I thought that the problem might have something to do with the :after styles being added only when the menu is fully expanded. Specifically, the class current is added to the LI tag once the menu is fully expanded. But commenting out the code that toggles that class seems to have no effect.

$(document).ready(function() {
  $('#group-subnav > ul > li > a').on('click', function(e) {
    e.preventDefault();
    var $li = $(this).closest('li');
    $li.find('ul').slideToggle('', function() {
      $li.toggleClass('current')
    }).end().siblings().find('ul').slideUp('', function() {
      $li.siblings().removeClass('current')
    }).end();
  });
});
/* Normalize */

body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td {
  margin:0;
  padding:0;
}
ol,ul {
  list-style:none;
}


#group-subnav {
  display: table-cell;
  vertical-align: top;
  background: #f6ca00;
  width: 159px;
  height: 100%;
}

#group-subnav a {
  display: block;
  color: inherit;
  text-decoration: none;
}

#group-subnav a:hover {
  /*    text-decoration: underline;*/
}

#group-subnav>ul {}

#group-subnav>ul>li {
  border-top: 2px solid #fff;
  font-size: 80%;
  text-shadow: 1px 1px 2px #eee;
  color: #333;
  letter-spacing: 1px;
  line-height: 1.2em;
  background: #bebebe;
  /* Old browsers */
}

#group-subnav>ul>li>a {
  padding: 6px 8px 12px;
  background: #bebebe;
  /* Old browsers */
  background: -moz-linear-gradient(top, #bebebe 0%, #b3b3b3 50%, #808080 100%);
  /* FF3.6+ */
  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #bebebe), color-stop(50%, #b3b3b3), color-stop(100%, #808080));
  /* Chrome,Safari4+ */
  background: -webkit-linear-gradient(top, #bebebe 0%, #b3b3b3 50%, #808080 100%);
  /* Chrome10+,Safari5.1+ */
  background: -o-linear-gradient(top, #bebebe 0%, #b3b3b3 50%, #808080 100%);
  /* Opera 11.10+ */
  background: -ms-linear-gradient(top, #bebebe 0%, #b3b3b3 50%, #808080 100%);
  /* IE10+ */
  background: linear-gradient(top, #bebebe 0%, #b3b3b3 50%, #808080 100%);
  /* W3C */
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#bebebe', endColorstr='#808080', GradientType=0);
  /* IE6-9 */
}

#group-subnav>ul>li>a:after {
  content: ' +';
  float: right;
}

#group-subnav>ul>li.current>a:after,
#group-subnav>ul>li:hover>a:after {
  font-size: 75%;
  content: ' 25bc';
}

#group-subnav>ul>li>ul {
  display: none;
  background: #f4e693;
  padding: 2em 0;
}

#group-subnav>ul>li.current>ul
/*,
            #group-subnav > ul > li:hover > ul*/

{
  display: block;
}

#group-subnav>ul>li>ul>li {
  text-shadow: none;
  padding: 5px 8px;
  border-bottom: 1px solid #e5b502;
  color: #666;
  font-size: 90%;
  letter-spacing: 0;
}

#group-subnav>ul>li>ul>li:first-child {
  border-top: 1px solid #e5b502;
}

#group-subnav>ul>li>ul>li>a {
  color: inherit;
  text-decoration: none;
}

#group-subnav>ul>li>ul>li>a:after {
  content: "0a0>";
}

#group-subnav>ul>li>ul>li>a:hover {
  text-decoration: underline;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<nav id="group-subnav">
  <!-- one column wide -->
  <ul>
    <li class="current"><a href="#">Services</a>
      <ul>
        <li><a href="#">Workflow Analysis</a></li>
        <li><a href="#">Technology Assessment</a></li>
        <li><a href="#">Precision Conversion</a></li>
        <li><a href="#">Intelligent Indexing</a></li>
        <li><a href="#">Simple Search and Retrieval</a></li>
        <li><a href="#">Better Forms Management</a></li>
        <li><a href="#">Effortless Distribution</a></li>
        <li><a href="#">Total Security</a></li>
        <li><a href="#">Easier Regulatory Compliance</a></li>
        <li><a href="#">Scanning</a></li>
      </ul>
    </li>
    <li><a href="#">Benefits</a>
      <ul>
        <li>Faster Storage and Retrieval</li>
        <li>Meticulous Records Management</li>
        <li>Disaster Prevention and Recovery</li>
        <li>Heightened Security</li>
        <li>Freed-up Physical Space</li>
        <li>Responsive Customer Service</li>
      </ul>
    </li>
    <li><a href="#">Get Started</a>
      <ul>
        <li>Call our Strategic Services Manager to get started.<br>
          <li><a href="mailto:">Email</a></li>
      </ul>

      </li>
  </ul>
</nav>

View on jsFiddle

Answer

Give the element you are slidetoggling a set width.

http://jsfiddle.net/5gGum/6/

    #group-subnav > ul > li > ul {
        display: none;
        background: #f4e693;
        padding: 2em 0;
        width: 159px;
    }

This allows jQuery to accurately calculate the end height.

For reference, I learned about this little trick from here: http://www.bennadel.com/blog/2263-Use-jQuery-s-SlideDown-With-Fixed-Width-Elements-To-Prevent-Jumping.htm

Leave a Reply

Your email address will not be published. Required fields are marked *