Search code examples
javascriptjqueryhtmlcssslidetoggle

Span text wrap issue during slideToggle() animation


The problem is that while slideToggle() is animating the span tags don't have proper text wrapping. Only once the animation finishes the span content is wrapper correctly.

I am trying to add more content on button press with jQuery. Not just plop it in, but rather have some kind of animation such as what slideToggle() provides.

Is there a fix for this or how can I implement it slightly differently to avoid the content not wrapping during the animation.

Here is an example:

$('.toggle').click(function() {
	$('.moreContent').slideToggle();
});
p {
  max-width: 300px;
}
.hide {
  display: none;
}
<p>
  <span><strong>List: </strong></span>
  Lorem ipsum dolor sit, amet consectetur adipisicing elit. Neque, beatae.
  <span class="hide moreContent">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Sit voluptate consequuntur corporis sint sequi quam maxime eius iusto perspiciatis.</span>
  <br>
  <br>
  <button class="toggle">Toggle</button>
</p>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>


Solution

  • The jump exists because in order to animate the slide the span has to have a height but it can only have a height if it is display: inline-block or display: block, which it means it will also have a width. You can see that jQuery is adding display: inline-block to the style attribute on the element while it's animated. When the animation is done, jQuery removes the style attribute and it goes back to the previous layout, i.e. inline.

    I don't know what your use case is or which parts are important (e.g. is the slide animation the important part or simply that something is animated in? Must it end on a sentence? Be two lines? Etc, etc). Below are a couple of examples that might give you some ideas to explore.

    First, instead of relying on jQuery to handle the animations, you can use it to toggle a class and define the animation in the CSS. The first example sets the container height to a max of 2em and overflow: hidden (so 2 lines will be shown and the rest hidden). Then, clicking the toggle button toggles the class and when the .show_all class is added, it animates the max-height property which results in a slide animation. The max-height just needs to be big enough to show whatever content might be in the container. If it's hugely variable you could set it to some large number (since it won't take up the space unless it needs it). However, you might need to tweak your animations numbers.

    The second example uses opacity and sets the animation to fade the text in/out when toggle is clicked. The hidden text still takes up space, so if you didn't want that, you could play with the CSS to workaround that. Maybe give the hidden text a negative z-index and play with the margin or positioning of the toggle button.

    I'm assuming you've set up a simple example so I didn't want to get too much into the details but just wanted to provide some other ways of tackling the problem.

    $('.toggle').click(function() {
      $('.content').toggleClass('show_all');
    });
    
    $('.toggle-fade').click(function() {
      $('.showme').toggleClass('show_all');
    });
    p {
      max-width: 300px;
      line-height: 1em;
    }
    
    .content {
      max-height: 2em;
      overflow: hidden;
      display: inline-block;
      transition: max-height .5s ease-in-out;
      text-wrap: none;
    }
    
    .show_all {
      max-height: 10em;
      height: auto;
    }
    
    .showme {
      opacity: 0;
      transition: opacity .3s ease-in-out;
    }
    
    .showme.show_all {
      opacity: 1;
    }
    <p>
      <span><strong>List: </strong></span>
      <span class="content">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Neque, beatae.
      Lorem, ipsum dolor sit amet consectetur adipisicing elit. Sit voluptate consequuntur corporis sint sequi quam maxime eius iusto perspiciatis.</span>
      <br>
      <br>
      <button class="toggle">Toggle</button>
    </p>
    
    <p>
      <span><strong>List: </strong></span>
      <span class="shown">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Neque, beatae.</span>
      <span class="showme">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Sit voluptate consequuntur corporis sint sequi quam maxime eius iusto perspiciatis.</span>
      <br>
      <br>
      <button class="toggle-fade">Toggle</button>
    </p>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>