smooth transition on content change

108
January 01, 2020, at 9:40 PM

I have a DIV of unknown height with content that can be changed from a javascript event. When the content changes, the DIV resizes to fit the new content. What I'm trying to do is have the DIV transition to the different height smoothly rather than abruptly.

I've tried adding this in to the DIV's CSS but it doesn't help. Not unless I set a specific height of the element.

transition: height 1s linear;

Is there a simple way to do this based on the content? Or do I have no choice but to write a javascript function and control it manually.?

Answer 1

In that case, create a separate transition class and add that class to that DIV along with the Javascript event.

document.getElementById('divID').className='CssTransitionClassName';
Answer 2

The basic strategy is to manually do what the browser refuses to: calculate the full size of the element's contents, then CSS transition the element to that explicit pixel size.

A Js solution which i prefer

// This is the important part! 
 
function collapseSection(element) { 
  // get the height of the element's inner content, regardless of its actual size 
  var sectionHeight = element.scrollHeight; 
   
  // temporarily disable all css transitions 
  var elementTransition = element.style.transition; 
  element.style.transition = ''; 
   
  // on the next frame (as soon as the previous style change has taken effect), 
  // explicitly set the element's height to its current pixel height, so we  
  // aren't transitioning out of 'auto' 
  requestAnimationFrame(function() { 
    element.style.height = sectionHeight + 'px'; 
    element.style.transition = elementTransition; 
     
    // on the next frame (as soon as the previous style change has taken effect), 
    // have the element transition to height: 0 
    requestAnimationFrame(function() { 
      element.style.height = 0 + 'px'; 
    }); 
  }); 
   
  // mark the section as "currently collapsed" 
  element.setAttribute('data-collapsed', 'true'); 
} 
 
function expandSection(element) { 
  // get the height of the element's inner content, regardless of its actual size 
  var sectionHeight = element.scrollHeight; 
   
  // have the element transition to the height of its inner content 
  element.style.height = sectionHeight + 'px'; 
 
  // when the next css transition finishes (which should be the one we just triggered) 
  element.addEventListener('transitionend', function(e) { 
    // remove this event listener so it only gets triggered once 
    element.removeEventListener('transitionend', arguments.callee); 
     
    // remove "height" from the element's inline styles, so it can return to its initial value 
    element.style.height = null; 
  }); 
   
  // mark the section as "currently not collapsed" 
  element.setAttribute('data-collapsed', 'false'); 
} 
 
document.querySelector('#toggle-button').addEventListener('click', function(e) { 
  var section = document.querySelector('.section.collapsible'); 
  var isCollapsed = section.getAttribute('data-collapsed') === 'true'; 
     
  if(isCollapsed) { 
    expandSection(section) 
    section.setAttribute('data-collapsed', 'false') 
  } else { 
    collapseSection(section) 
  } 
});
.container .section { 
  overflow: hidden; 
  transition: height 0.3s ease-out; 
  height: auto; 
} 
 
* { 
  box-sizing: border-box; 
} 
 
body { 
  margin: 0; 
  padding: 10vh 10vw; 
  font-family: arial; 
} 
 
p { 
  margin: 10px; 
} 
 
.container { 
  border: 3px solid #ffeb3b; 
  margin: 0 auto; 
  max-width: 300px; 
  border-radius: 3px; 
} 
.container .section { 
  border: 3px solid #4caf50; 
} 
 
button { 
  display: block; 
  --webkit-appearance: none; 
  font-size: 18px; 
  border: none; 
  border-radius: 3px; 
  background: #2196f3; 
  color: white; 
  margin: 15px auto; 
  padding: 15px; 
  cursor: pointer; 
  transition: box-shadow 0.2s ease-out; 
} 
button:hover { 
  box-shadow: 0px 0px 15px lightgrey; 
} 
button:active { 
  box-shadow: 0px 0px 10px lightgrey; 
} 
button:focus { 
  outline: none; 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> 
<div class="container"> 
  <div class="section"> 
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p> 
  </div> 
  <div class="section collapsible"> 
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p> 
  </div> 
  <div class="section"> 
   <p>Ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p> 
  </div> 
</div> 
 
<button id="toggle-button">Toggle collapse</button>

You can read further Reference

Answer 3

This could be what you are looking for: Animating a div while it fits to dynamically loaded content

I refactored their solution here to account for adding content, though you can add/remove/alter it any way you need. This will animate to new height and width with appended content, regardless of the amount of content added.

There is more to the code than this, but these are the basic steps of what's involved:

/* 1: Append Content to the animated element */
$(element).append(content);
/* 2: Set height & width to auto */
$(element).css({'width':'auto','height':'auto', 'padding':'15px 25px'});
/* 3: Set height & width to an initial value*/
$(element).css({'width':oldWidth+'px','height':oldHeight+'px'});
/* 4: Animate to the final values */
$(element).animate({
  'width':contentWidth+'px',
  'height':contentHeight+'px',
  'padding':'15px 25px'
}, 500);

You can alter the content variable to be whatever html content you need, or change $(element).append() to $(element).html() to alter the contents completely instead of just appending items to them.

READ ALSO
parallax scroll effect getting laggy

parallax scroll effect getting laggy

i wrote a script that basically gives the topper element a negative margin bottom, so it makes the element below it go up and it kind of makes a parallax like scroll, my problem is i wrote the function as a scroll and i think the function runs so much that it makes the page kind of laggy,...

68
Spider Error Processing - Python Web Scraping Error

Spider Error Processing - Python Web Scraping Error

I am new to Python and very new to web scraping, but I am trying to build a web scraper for this site: https://wwwfortune

111
Merging HTML &amp; JavaScript

Merging HTML & JavaScript

I'm editing a section of an open source web-pageIt gives logos of companies

73